こんにちは, Shinoryoです.
今回はHHKB プログラミングコンテスト 2020を, Pythonで解いてみた結果を書き連ねていこうと思います.
HHKB Programming Contest 2020 - AtCoder
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
A - Keyboard
大文字にするには.upperを使用します.
# 入力 | |
s = input() | |
t = input() | |
# 大文字にするには.upperを使用 | |
if s == "Y": | |
print(t.upper()) | |
else: | |
print(t) |
B - Futon
「今いるマスとその右マスがともに空いているなら
# 入力 | |
h, w = [int(i) for i in input().split()] | |
s = [input() for _ in range(h)] | |
# 答えを格納 | |
ans = 0 | |
# 今いるマスとその右マスがともに空いているなら+1 | |
# 今いるマスとその下マスがともに空いているなら+1 | |
for i in range(h): | |
for j in range(w): | |
if j != w-1 : | |
if s[i][j] == "." and s[i][j+1] == "." : | |
ans += 1 | |
if i != h-1 : | |
if s[i][j] == "." and s[i+1][j] == "." : | |
ans += 1 | |
# 答えを出力 | |
print(ans) |
C - Neq Min
問題文にあることをそのまま律儀に実行することもできますが, 時間計算量が膨大になってしまい, TLE.
# 入力 | |
n = int(input()) | |
p = [int(i) for i in input().split()] | |
# 各iに関して | |
for i in range(n) : | |
# 出力値の初期値 | |
output = 0 | |
# 配列を切り出す | |
p2 = set(p[:i+1]) | |
# 0から調査 | |
while output in p2 : | |
output += 1 | |
# 出力 | |
print(output) |
そこで,
# pmax | |
pmax = 200001 | |
# 入力 | |
n = int(input()) | |
p = [int(i) for i in input().split()] | |
# 整数が登場したかのフラグを格納する配列 | |
a = [False for _ in range(pmax)] | |
# 出力値の初期値 | |
ans = 0 | |
# 各iに関して | |
for i in range(n) : | |
# 整数p[i]が登場したフラグを立てる | |
a[p[i]] = True | |
# 前回の出力値以上の値に関して調査 | |
for j in range(ans, pmax): | |
# 整数ansが登場していないなら、それが出力すべき値 | |
if a[ans] == False: | |
break | |
# ansに+1して再調査 | |
ans += 1 | |
# 出力 | |
print(ans) |
D - Squares
以下のようにして求めるようです.
-
求める答えを
とします. 赤い正方形と青い正方形を敷き詰める場合の総数は なので, 赤い正方形の内部と青い正方形の内部が重なるように置く場合の数を とすれば, となります. -
「赤い正方形の内部と青い正方形の内部が重なる」は「赤い正方形の
座標と青い正方形の 座標が重なる」かつ「赤い正方形の 座標と青い正方形の 座標が重なる」となります. したがって, 1次元的に長さ の区間と長さ の区間を長さ の区間に詰めたとき, 区間が重なる置き方の総数を とすれば, となります. -
長さ
の区間と長さ の区間を長さ の区間に詰める場合の総数は なので, 長さ の区間と長さ の区間を長さ の区間に詰めたとき, 区間が重ならない置き方の総数を とすると, となります. -
長さ
の区間と長さ の区間を長さ の区間に詰めたとき, 区間が重ならない置き方の総数というのは,- 空白部分
個 - 赤い部分
個(つながっているものはまとめて 個と見なす) - 青い部分
個(つながっているものはまとめて 個と見なす)
となります. - 空白部分
以上を利用すれば, 各テストケースに対して定数時間(
# mod | |
mod = 1000000007 | |
# 入力:int型N,A,B | |
# 出力:赤い正方形の内部と青い正方形の内部が重ならない置き方の総数 | |
def ans(Nin, Ain, Bin): | |
return (((Nin - Ain + 1)**2)*((Nin - Bin + 1)**2) - x1(Nin, Ain, Bin)) % mod | |
# 入力:int型N,A,B | |
# 出力:赤い正方形の内部と青い正方形の内部が重なる置き方の総数 | |
def x1(Nin, Ain, Bin): | |
return x2(Nin, Ain, Bin)**2 | |
# 入力:int型N,A,B | |
# 出力:長さAの区間と長さBの区間を長さNの区間に詰めたとき、区間が重なる置き方の総数 | |
def x2(Nin, Ain, Bin): | |
return (Nin - Ain + 1)*(Nin - Bin + 1) - x3(Nin, Ain, Bin) | |
# 入力:int型N,A,B | |
# 出力:長さAの区間と長さBの区間を長さNの区間に詰めたとき、区間が重ならない置き方の総数 | |
def x3(Nin, Ain, Bin): | |
# 空白マスが作れなければ0であることに注意 | |
if Nin - Ain - Bin < 0: | |
return 0 | |
else: | |
return (Nin - Ain - Bin + 2)*(Nin - Ain - Bin + 1) | |
# T入力 | |
T = int(input()) | |
# T回ループ | |
for _ in range(T): | |
# NAB入力 | |
N, A, B = [int(x) for x in input().split()] | |
# 答えを出力 | |
print(ans(N, A, B)) |
E以降
E以降は私の能力不足故に省略いたします.
参考にしたサイト等
- 「解説 - HHKB プログラミングコンテスト 2020」
Editorial - HHKB Programming Contest 2020
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
- nkmk様による「Pythonで大文字・小文字を操作する文字列メソッド一覧」
Pythonで大文字・小文字を操作する文字列メソッド一覧 | note.nkmk.me
Pythonの文字列型(str型)には大文字・小文字を操作する便利なメソッドが標準で用意されている. 大文字と小文字を変換したり判定したりできる. 組み込み型: 文字列メソッド — Python 3.7.2 ドキュメント ここでは以下の内容について説明する. 大文字と小文字の変換基本的な使い方全角と半角の扱いstr.upper(): すべての文...
0 件のコメント:
コメントを投稿 (Please feel free to ask me about your questions! You can use Japanese or English in the comments.)