こんにちは, Shinoryoです.
今回は第四回日本最強プログラマー学生選手権-予選-(AtCoder Beginner Contest 313)を, Pythonで解いてみた結果を書き連ねていこうと思います.
AtCoder Beginner Contest 313 - AtCoder
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
目次[非表示]
A - To Be Saikyo
# 入力 | |
N = int(input()) | |
P = list(map(int, input().split())) | |
# 1人の場合 | |
if N < 2: | |
print(0) | |
exit() | |
# 2人以上の場合 | |
max_power = max(P[1:]) | |
if P[0] > max_power: | |
print(0) | |
else: | |
print(max_power - P[0] + 1) |
B - Who is Saikyo?
ある人
# 入力 | |
N, M = map(int, input().split()) | |
# メンバーのリストから弱い人を消していく | |
remaining = set(range(1, N + 1)) | |
for _ in range(M): | |
_, B = map(int, input().split()) | |
remaining.discard(B) | |
# 出力 | |
if len(remaining) == 1: | |
print(remaining.pop()) | |
else: | |
print(-1) |
C - Approximate Equalization 2
今回の操作では, 整数列
の平均値よりも大きい項: の平均値の切り上げ値になるまで減算する(減算回数 ) の平均値以下の項: の平均値の切り捨て値になるまで加算する(加算回数 )
問題文の制約によって,
# 入力 | |
N = int(input()) | |
A = list(map(int, input().split())) | |
# Aの平均値とその切り捨て・切り上げを求める | |
sum_A = sum(A) | |
ave_A = sum_A / N | |
ave_A_floor = sum_A // N | |
ave_A_ceil = (sum_A + N - 1) // N | |
# 減算する回数と加算する回数を求める | |
decrement_count = 0 | |
increment_count = 0 | |
for i in range(N): | |
if A[i] <= ave_A: | |
decrement_count += ave_A_floor - A[i] | |
else: | |
increment_count += A[i] - ave_A_ceil | |
# 出力 | |
print(max(increment_count, decrement_count)) |
D - Odd or Even
解説にある解法の通りです. 偶奇の計算の際には排他的論理和 XORを適切に用いることができます.
# 入力 | |
N, K = map(int, input().split()) | |
# 求める整数列A | |
A = [0 for _ in range(N)] | |
# クエリの応答結果を格納しておく数列T | |
T = [0 for _ in range(N)] | |
# A_1からA_(K + 1)までのパリティ | |
parity_from_1_to_K_plus_1 = 0 | |
# A_1からA_(K + 1)までを求める | |
for i in range(K + 1): | |
query_x = [x % (K + 1) + 1 for x in range(i, i + K)] | |
print("?", *query_x) | |
T[i] = int(input()) | |
parity_from_1_to_K_plus_1 ^= T[i] | |
for i in range(K + 1): | |
A[i] = parity_from_1_to_K_plus_1 ^ T[(i + 1) % (K + 1)] | |
# A_(K + 2)からA_Nまでを求める | |
for i in range(K + 1, N): | |
print("?", *range(1, K), i + 1) | |
T[i] = int(input()) | |
for j in range(K - 1): | |
T[i] ^= A[j] | |
A[i] = T[i] | |
# 出力 | |
print("!", *A) |
E以降
E以降は私の能力不足故に省略いたします.
参考にしたサイト等
- 「解説 - 第四回日本最強プログラマー学生選手権-予選-(AtCoder Beginner Contest 313)」
Editorial - AtCoder Beginner Contest 313
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にはビット演算子として&, |, ^, ~, <<, >>が用意されている. 2進数で表した整数intの各ビットに対して, それぞれ論理積, 論理和, 排他的論理和, ビット反転, 左ビットシフト, 右ビットシフトを行う. 論理積(AND), 論理和(OR), 排他的論理和(XOR)の入出力 ビット単位論理積(bitwise AND): &演算子 ビット単位...
0 件のコメント:
コメントを投稿 (Please feel free to ask me about your questions! You can use Japanese or English in the comments.)