ABC269の振り返り(A, B, C, D, E)
振り返りです。
def test_all(f): for i, data in enumerate(eval(f'test_data{f.__name__}')): exp = data["out"] ans = f(*data["in"]) result = "AC" if exp == ans else "WA" print(f"{i+1} {result}: expected: {exp}, output: {ans}")A - Anyway Takahashi
略
B - Rectangle Detection
やってみよう!
B
関数を完成させて「Run」ボタンをクリックしよう!
自由欄
try
コンテスト中の提出が微妙なので、振り返ってやり直すとこんな感じ。
何気にzip
転置の使い所が多い気がする。
結果:#35652753
自由欄
C - Submask
やってみよう!
C
関数を完成させて「Run」ボタンをクリックしよう!
自由欄
try(コンテスト中)
from itertools import product def C(N): ones = [i for i, f in enumerate(bin(N)[2:][::-1]) if f == "1"][::-1] for c in product([0, 1], repeat=len(ones)): n = sum([2**exp for exp, f in zip(ones, c) if f == 1]) print(n) return test_all(C)結果:#34939876
try(振り返り)
上を見ずに振り返って再挑戦しました。
結果、やってることは大体一緒です。
結果:#35653766
自由欄
D - Do use hexagon grid
やってみよう!
D
関数を完成させて「Run」ボタンをクリックしよう!
自由欄
try(コンテスト中)
愚直に幅優先探索です。
from collections import deque def is_neighbor(a, b): return ( (a[0] - 1 == b[0] and a[1] - 1 == b[1]) or (a[0] - 1 == b[0] and a[1] == b[1]) or (a[0] == b[0] and a[1] - 1 == b[1]) or (a[0] == b[0] and a[1] + 1 == b[1]) or (a[0] + 1 == b[0] and a[1] == b[1]) or (a[0] + 1 == b[0] and a[1] + 1 == b[1]) ) def D(N, XY): ret = 0 remaind = set(range(0, N)) while len(remaind): ret += 1 q = deque([remaind.pop()]) while len(q): now = q.popleft() for i in list(remaind): if is_neighbor(XY[now], XY[i]): remaind.remove(i) q.append(i) return ret test_all(D)結果:#34946386
try(振り返り)
このコンテストに参加した時点ではまだABC264の振り返りをしてなかったので知る由もないのですが…
これ、ABC264:E問題で使ったUnion Findが使えそう…!!
というわけでDSU(まだ自分の中で呼び名が定着してないです😇)を使った提出が以下。
計算量的には上のBFSと同じ$O(N^2)$ですかね。
コーディング量が若干少なくなったので時間短縮に繋がりそうです🌝
結果:#35655758
解説を見る
解説を見ると、やっぱりDSU使ってました。
が、着目しているマスに隣接するマスだけを探すことで$O(N)$の計算量に抑えられています。
こういうところの詰めが甘い…。反省です。
def D(N, XY): contain = [[-1] * 20010 for _ in range(2010)] for i, (x, y) in enumerate(XY): contain[x+1005][y+1005] = i dsu = [-1] * N def leader(i): if dsu[i] < 0: return i dsu[i] = leader(dsu[i]) return dsu[i] def merge(i, j): '''サイズの大きい方(x)に小さい方(y)をマージ''' if i == j: return x = leader(i) y = leader(j) if x == y: return if dsu[x] > dsu[y]: x, y = y, x dsu[x] += dsu[y] dsu[y] = x def get_neighbors(i, j): return ( [i-1,j-1], [i-1,j], [i,j-1], [i,j+1], [i+1,j], [i+1,j+1], ) for i, (x, y) in enumerate(XY): for s, t in get_neighbors(x, y): idx = contain[s+1005][t+1005] if idx > -1: merge(i, idx) return sum(1 for n in dsu if n < 0) # 提出用 # N = int(input()) # XY = [list(map(int, input().split())) for _ in range(N)] # print(D(N, XY)) test_all(D)結果:#35656907
なぜか実行時間が3倍ほどに延びてしまいました…
Nがもっと大きかったら効果あるのかなぁ🤔
自由欄
E - Last Rook
初のインタラクティブ問題!
とりあえず、コンテスト終了後にACしたコードを貼っときます。
N = int(input())
def main(N):
for i in range(2):
s = 1
e = N + 1
while e - s > 0:
# print(s, e)
m = (s + e) // 2
if i == 0:
print(f"? {s} {m} {1} {N}")
else:
print(f"? {1} {N} {s} {m}")
ans = int(input())
if ans == -1: return
elif ans == m - s + 1:
s = m + 1
else:
e = m
else:
if i == 0:
x = s
else:
y = s
print(f"! {x} {y}")
main(N)
結果:#34956135
半開区間とか閉区間とか
二分探索に通ずる部分ですが、ここらへんの理解が怪しいので色々試してみました。
半開区間:[ok, ng)
N = int(input())
def main(N):
def bs(f):
def is_ok(m):
f(ok, m)
ans = int(input())
return ans == m - ok
ok = 1
ng = N + 1
while abs(ok - ng) > 1:
m = (ok + ng) // 2 - 1
if is_ok(m):
ng = m + 1
else:
ok = m + 1
return ok
x = bs(lambda s, m: print(f"? {s} {m} {1} {N}"))
y = bs(lambda s, m: print(f"? {1} {N} {s} {m}"))
print(f"! {x} {y}")
main(N)
結果:#35729412
半開区間:(ng, ok]
N = int(input())
def main(N):
def bs(f):
def is_ok(m):
f(m, ok)
ans = int(input())
return ans == ok - m
ng = 0
ok = N
while abs(ok - ng) > 1:
m = (ok + ng) // 2 + 1
if is_ok(m):
ng = m - 1
else:
ok = m - 1
return ok
x = bs(lambda s, m: print(f"? {s} {m} {1} {N}"))
y = bs(lambda s, m: print(f"? {1} {N} {s} {m}"))
print(f"! {x} {y}")
main(N)
結果:#35730449
閉区間:[ok, ng]
N = int(input())
def main(N):
def bs(f):
def is_ok(m):
f(ok, m)
ans = int(input())
return ans == m - ok
ok = 1
ng = N
while abs(ok - ng) > 0:
m = (ok + ng) // 2
if is_ok(m):
ng = m
else:
ok = m + 1
return ok
x = bs(lambda s, m: print(f"? {s} {m} {1} {N}"))
y = bs(lambda s, m: print(f"? {1} {N} {s} {m}"))
print(f"! {x} {y}")
main(N)
結果:#35729641
う~ん、まだ身についてない気がする…