[AtCoder]HHKB プログラミングコンテスト 2020個人的メモ[Python]
HHKB2020
所感
ABC3完,1032パフォ
思ったよりもパフォーマンスが出たので良かった
A - Keyboard
文字列を大文字に変換する方法を覚えてなかったのでググった
提出コード
#!/usr/bin/env python3
def main():
S = input()
T = input()
print(T if S == "N" else T.upper())
if __name__ == '__main__':
main()
B - Futon
二重のfor文で全探索
各点から,現在点と右のマスは共に布団を置けるマスか?,現在点と下のマスは共に布団を置けるか?をチェック
リストのインデックスエラーに注意
提出コード
#!/usr/bin/env python3
def main():
H, W = map(int, input().split())
S = [list(input()) for _ in range(H)]
ans = 0
for i in range(H):
for j in range(W):
if i + 1 < H and S[i][j] == S[i + 1][j] == ".":
ans += 1
if j + 1 < W and S[i][j] == S[i][j + 1] == ".":
ans += 1
print(ans)
if __name__ == '__main__':
main()
C - Neq Min
i回目の出力をxとした時,それ以降の出力がx以下になることは無い
何故なら,それ以前のpによって,x未満の数字は出禁になっているから
よって,以下のようなコードを組めばおk
計算量は
提出コード
#!/usr/bin/env python3
def main():
N = int(input())
P = [int(x) for x in input().split()]
num_max = 10 ** 5 * 2 + 1
lst = [True] * num_max
ans = 0
for p in P:
lst[p] = False
while lst[ans] is False:
ans += 1
print(ans)
if __name__ == '__main__':
main()
D - Squares
サンプルすらacしなかった
いろいろ考えたが,残り30分ぐらいからほぼ思考停止状態でもったいなかった
制約とか入力方法とかで,何か工夫して1クエリの計算量は
ほとんど公式解説と同じだが,一応説明
赤い正方形,青い正方形の全ての場合の数はそれぞれ以下の様になる
ここから,赤と青が重複して配置される場合の数
の両方が同時に成り立っている場合の数
つまり,両者を掛け算すれば求まる
とはいえ,対称性により両者の場合の数は等しいから,
となる
ということで,
とりあえず,A,Bを区別しないとする
□を空白として,□...□赤□...□青□...□のように空白の中に長さA,Bの赤,青を挿入すると考える
すると,赤と青を区別しないと
通りの組み合わせがあると分かる
実際は赤と青は区別して考えるので
となる
よって,
となる
提出コード
#!/usr/bin/env python3
def solve(N, A, B):
MOD = 10 ** 9 + 7
if A + B > N:
return 0
ab = (N - A + 1) * (N - B + 1)
comb = (N - A - B + 2) * (N - A - B + 1)
return (pow(ab, 2, MOD) - pow(ab - comb, 2, MOD)) % MOD
def main():
from sys import stdin
input = stdin.readline
T = int(input())
for _ in range(T):
N, A, B = map(int, input().split())
print(solve(N, A, B))
if __name__ == '__main__':
main()
E - Lamps
散らかっているマスを壁,散らかっていないマスを道とする
ある1つの道のマス(i, j)に注目し,
全ての道マスにおいて
よって,
で,
で,
というわけで
で,
しかし,各マスから4方向に連続する道マスを数えると計算量が最大で
なので,下図の様に各マスごとではなく,各行ごとに連続するマスを数えていくことにする
列はリストを転置することで行と同じように数えた
ただし,この方法だと各マス自身を重複して数えてしまうので,列を数える際には-1した
こうすると,計算量は
最後の2のべき乗の計算は事前計算せずに,forループの中で計算させるとTLEしたので注意
リストを回転するところがかなり時間かかっている
実際,2回転させたらTLEした
参考にさせてもらった提出 #17307568では回転させておらず実行時間が400ms
僕のは1191ms
提出コード
#!/usr/bin/env python3
def input_num_of_continuous(head, end, now_h, cnt, is_not_first):
"""
壁にぶつかるまでに通ったマスに対して,連続していたマスの数を加算
自分のマスを重複して数えない様に初回以外は1引く
"""
res = 1 if is_not_first else 0
for k in range(head, end):
cnt[now_h][k] += end - head - res
return cnt
def solve(H, W, S):
MOD = 10 ** 9 + 7
cnt = [[0] * W for _ in range(H)]
for n in range(2):
if n:
# 各マスを数えた結果cnt,与えられたSを転置
cnt = [list(x) for x in zip(*cnt)]
S = [list(x) for x in zip(*S)]
H, W = W, H
for i in range(H):
head = 0
for j in range(W):
if S[i][j] == "#":
# head == jだと#が連続しているのでheadを動かすだけ
if head != j:
cnt = input_num_of_continuous(head, j, i, cnt, n)
head = j + 1
# 端に達した時の連続数で通った道に加算
cnt = input_num_of_continuous(head, W, i, cnt, n)
# LUT
pow2 = [1] * (H * W + 1)
for i in range(H * W):
pow2[i + 1] = pow2[i] * 2 % MOD
K = sum([row.count(".") for row in S])
ans = 0
for row in cnt:
for n in row:
ans += pow2[K] - pow2[K - n]
ans %= MOD
return ans % MOD
def main():
import sys
input = sys.stdin.readline
H, W = map(int, input().split())
S = [input().rstrip() for _ in range(H)]
print(solve(H, W, S))
main()
参考資料
- Pythonで大文字・小文字を操作する文字列メソッド一覧 | note.nkmk.me
https://note.nkmk.me/python-capitalize-lower-upper-title/ - 【AtCoder解説】PythonでHHKB2020のA,B,C問題を制する! - Qiita
https://qiita.com/u2dayo/items/f685997847d583227d06 - [AtCoder 参加感想] 2020/10/10:HHKBプログラミングコンテスト2020 | maspyのHP
https://maspypy.com/atcoder-参加感想-2020-10-10hhkbプログラミングコンテスト2020 - HHKB プログラミングコンテスト 2020 E - Lamps (500 点) - けんちょんの競プロ精進記録
https://drken1215.hatenablog.com/entry/2020/10/11/155900 - AtCoder ABC 129 D - Lamp (400 点) - けんちょんの競プロ精進記録
https://drken1215.hatenablog.com/entry/2019/06/10/143300 - Pythonリスト型の二次元配列の行と列を入れ替える(転置) | note.nkmk.me
https://note.nkmk.me/python-list-transpose/ - 提出 #17307568 - HHKB プログラミングコンテスト 2020
https://atcoder.jp/contests/hhkb2020/submissions/17307568 - 提出 #17308590 - HHKB プログラミングコンテスト 2020
https://atcoder.jp/contests/hhkb2020/submissions/17308590 - 解説 - HHKB プログラミングコンテスト 2020
https://atcoder.jp/contests/hhkb2020/editorial - 解説動画 - HHKB プログラミングコンテスト 2020
https://youtu.be/eus_giFYAIs
Discussion