振り返りです。
UNICORN Programming Contest 2022(AtCoder Beginner Contest 269) - AtCoder
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.

A - Anyway Takahashi
略
B - Rectangle Detection
やってみよう!
B
関数を完成させて「Run」ボタンをクリックしよう!
自由欄
try
コンテスト中の提出が微妙なので、振り返ってやり直すとこんな感じ。
何気にzip
転置の使い所が多い気がする。
結果:#35652753
自由欄
C - Submask
やってみよう!
C
関数を完成させて「Run」ボタンをクリックしよう!
自由欄
try(コンテスト中)
結果:#34939876
try(振り返り)
上を見ずに振り返って再挑戦しました。
結果、やってることは大体一緒です。
結果:#35653766
自由欄
D - Do use hexagon grid
やってみよう!
D
関数を完成させて「Run」ボタンをクリックしよう!
自由欄
try(コンテスト中)
愚直に幅優先探索です。
結果:#34946386
try(振り返り)
このコンテストに参加した時点ではまだABC264の振り返りをしてなかったので知る由もないのですが…
これ、ABC264:E問題で使ったUnion Findが使えそう…!!
というわけでDSU(まだ自分の中で呼び名が定着してないです😇)を使った提出が以下。
計算量的には上のBFSと同じ$O(N^2)$ですかね。
コーディング量が若干少なくなったので時間短縮に繋がりそうです🌝
結果:#35655758
解説を見る
解説を見ると、やっぱりDSU使ってました。
が、着目しているマスに隣接するマスだけを探すことで$O(N)$の計算量に抑えられています。
こういうところの詰めが甘い…。反省です。
結果:#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
う~ん、まだ身についてない気がする…