先週末のAtCorder 256に参加しました。
A, B、Cの3完でした。Cが解けた後に時間が少しあったのでDにチャレンジしてみたが正解に至りませんでした。
【A】 2^N
提出したコードはこちら
N = int(input())
print(2**N)
かつてないぐらい簡単なA問題だと思います。
【B】 Batters
提出したコードはこちら
N = int(input())
A = list(map(int, input().split()))
p = 0
koma = [] # コマがいるマスindex
for a in A: # O(1000)
# 既存コマ
new_koma = []
for k in koma: # O(4)
if k + a >= 4:
p += 1
else:
new_koma.append(k + a)
# コマ=0
if a == 4:
p += 1
else:
new_koma.append(a)
koma = new_koma
print(p)
問題は理解しやすく実現したいことは明確だけど、コードに落とすのはちょっと大変という感じで、良問だと思います。
Filling 3×3 array
提出したコードはこちら
def solution(hw):
ans = 0
# 1行目
h1 = hw[0]
masu_1_lines = []
for i in range(1, h1 + 1): # O(30)
for j in range(1, h1 + 1): # O(30)
if h1 - i - j <= 0:
break
else:
masu_1_lines.append([i, j, h1 - i - j])
# 2行目
h2 = hw
masu_2_lines = []
for i in range(1, h2 + 1): # O(30)
for j in range(1, h2 + 1): # O(30)
if h2 - i - j <= 0:
break
else:
masu_2_lines.append([i, j, h2 - i - j])
# masu_linesを結合して条件を満たすか確認
for m1 in masu_1_lines:
for m2 in masu_2_lines:
m3 = [
hw
- m1[0] - m2[0],
hw
- m1
- m2
,
hw[5] - m1
- m2
]
if m3[0] > 0 and m3
> 0 and m3
> 0 and sum(m3) == hw
:
ans += 1
return ans
hw = list(map(int, input().split()))
print(solution(hw))
# print(solution(
))
# print(solution(
))
# print(solution([5, 13, 10, 6, 13, 9]))
# print(solution([20, 25, 30, 22, 29, 24]))
これも問題自体は明確でわかりやすかったです。
一工夫が必要な全探索のパターンですね。まともに全探索やったら計算量的にNGですが、途中までやれば残りの値が決まるので、計算量を減らすことができるタイプの全探索です。
AtCorderの非公式(?)の最初の10問で、同じパターンの問題がありました。お年玉のやつです。
https://qiita.com/drken/items/fd4e5e3630d0f5859067#5-%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-10-%E5%95%8F
同じような問題をやったことがあったので、この問題は無事、解くことができました。
【D】 Union of Interval
珍しくC問題のあとに時間があまったので、Dnimoチャレンジしてみました。が、正解にはいたらず・・・
途中まで考えていた回答はこちら
def solution(LR):
ans = [] # [[L, R], [L,R]...]
for lr in LR:
start = int(lr.split()[0])
end = int(lr.split()
)
if len(ans) == 0:
ans.append([start, end])
continue
new_ans = []
for a in ans:
if a[0] <= start <= a
:
new_ans.append([a[0], max(end, a
)])
else:
new_ans.append(ans)
if a
< start:
new_ans.append([start, end])
ans = new_ans
print(ans)
for i, v in enumerate(ans):
if i == 0:
print(*v[0])
else:
print(*v)
# N = int(input())
# LR = [(input()) for _ in range(N)]
# solution(LR)
LR = ["10 20", "20 30", "40 50"]
solution(LR)
LR = ["10 40", "30 60", "20 50"]
solution(LR)
答えらしき値は出せていましたが、ansの配列の中身が違ってで正しく出力できず。まあこの問題が解決できていたとしても、正解だったのかどうか怪しいですね。。。
解説見たところ、ソートしてしまえば、今いるレンジとかぶるか、完全に外かを調べれば良いということがわかりました。
で、解説見た後、クリアできたコードはこちら
def solution(LR):
# LRは要素が文字列で正しくsortできないのでintのlistに変換
intLR = []
for lr in LR:
int_lr = tuple(map(int, lr.split()))
intLR.append(int_lr)
ans = [] # [[L, R], [L,R]...]
intLR.sort()
# 現在区間 sortすれば、現座区間に含まれるかそれよりあとの2択になる
# これが拡張されるから分離されるか調べていく
start = intLR[0][0]
end = intLR[0]
for lr in intLR:
l = lr[0]
r = lr
if l > end: # 現在の位置より後なので新区間になる
# endが更新されることはないので現在区間を確定
ans.append([start, end])
# 新区間
start = l
end = r
continue
if r > end: # 現在の区間を拡張
end = r
else:
# last区間
ans.append([start, end])
for a in ans:
print(*a)
N = int(input())
LR = [(input()) for _ in range(N)]
solution(LR)
# LR = ["10 20", "20 30", "40 50"]
# solution(LR)
# LR = ["10 40", "30 60", "20 50", "5 15"]
# solution(LR)
別解のimos法とやらは、よく見ても理解できませんでした。今回の問題では、ベストマッチしているアルゴリズムではなさそうなので、とりえず理解は諦めました・・・
まとめ
以上、AtCorder参加8回目でした。久しぶりにCが解けて嬉しくはあるのですが、やはり上を目指すためにも、今回ぐらいの問題だったDまで解けるようになりたいという思いがあります。
あと、いつも見ていたQiitaのPythonのコード解説がなくなったようなので、公式解説を見るしかなくなりました。公式解説はわかりづらいですし、コードもC++なのでつらいものがあります。C++はコード見ても、よくわからないです・・・😰
- 参加08回目 ABC255 2022/06/18 正解ABC 灰色
- 参加07回目 ABC255 2022/06/11 正解AB 灰色
- 参加06回目 ABC253 2022/05/28 正解AB 灰色
- 参加05回目 ABC252 2022/05/21 正解ABC 灰色
- 参加04回目 ABC251 2022/05/14 正解ABC 灰色
- 参加03回目 ABC250 2022/05/08 正解AB 灰色
- 参加02回目 ABC249 2022/04/23 正解AB 灰色
- 参加01回目 ABC247 2022/04/10 正解0問(登録だけ仕手未参加) 灰色
masu_2_lines = []
for i in range(1, h2 + 1): # O(30)
for j in range(1, h2 + 1): # O(30)
if h2 - i - j <= 0:
break
else:
masu_2_lines.append([i, j, h2 - i - j])
# masu_linesを結合して条件を満たすか確認
for m1 in masu_1_lines:
for m2 in masu_2_lines:
m3 = [
hw
- m1[0] - m2[0],
hw
- m1
- m2
