AtCoder Beginner Contest 343の解説記事です。
ABC343 A – Wrong Answer
問題
問題文の要約は以下の通りです。
問題の要約
\(0\)以上\(9\)以下の整数 \(A, B\) が与えられます。\(0\)以上\(9\)以下の整数であって \(A+B\) と等しくないものをいずれかひとつ出力せよ。
制約
・\(0 \le A \le 9\)
・\(0 \le B \le 9\)
・\(0 \le A+B \le 9\)
・\(A, B\) は整数
入力
\(A\) \(B\)
出力
\(0\)以上\(9\)以下の整数であって \(A+B\) と等しくないものをいずれかひとつ出力せよ。
解説
\(A+B\) を考え、等しくないものを出力する。
解説
まず入力 \(A\), \(B\)をint
型として受け取ります。
# 入力
A,B=map(int,input().split())
\(A\), \(B\)がともに0
であれば\(A+B=0\) となるので1
を出力、それ以外は\(A+B \ne 0\) となるので0
を出力します。
# AとBがともに0であれば1、それ以外は0を出力
if A==0 and B==0:
print(1)
else:
print(0)
解答
# 入力
A,B=map(int,input().split())
# AとBがともに0であれば1、それ以外は0を出力
if A==0 and B==0:
print(1)
else:
print(0)
ABC343 B – Adjacency Matrix
問題
解説
その列に含まれる要素が1である行の番号を出力する。
解説
まず入力 \(N\)をint
型として受け取ります。
# 入力
N = int(input())
\(N×N\)の行列を2次元配列として受け取る。
# N×Nの行列を受け取る
A = [list(map(int, input().split())) for _ in range(N)]
列ごとに1の位置を探索し、Aのj行i列の要素が1ならば、その行の番号を出力します。
# 列ごとに1の位置を探索する
for i in range(N):
# 行を探索
for j in range(N):
# もしAのj行i列の要素が1ならば、その行の番号を出力する
if A[j][i] == 1:
print(j + 1, end=' ')
# 改行
print()
解答
# 入力
N = int(input())
# N×Nの行列を受け取る
A = [list(map(int, input().split())) for _ in range(N)]
# 列ごとに1の位置を探索する
for i in range(N):
# 行を探索
for j in range(N):
# もしAのj行i列の要素が1ならば、その行の番号を出力する
if A[j][i] == 1:
print(j + 1, end=' ')
# 改行
print()
ABC343 C – 343
問題
解説
立法数を全探索し、その数が回文数かどうか判定する。
解説
まず入力 \(N\)をint
型として受け取ります。
# 入力
N = int(input())
回文立方数を格納する変数ans
を用意します。
# 回文立方数を格納する変数
ans = 1
10**7
までの数i
についてループを行い、各i
に対してi**3
として立方数を計算します。計算された立方数が \(N\) 以下であり、かつその数が回文(前から読んでも後ろから読んでも同じになる数)である場合、その数をans
に格納します。ループが終了すると、 \(N\) 以下で最大の回文立方数がans
に格納されているため、これを出力します。
# 10**7までの数でループを実行
for i in range(10**7):
# 立方数を計算
tmp = i**3
# 計算した立方数がN以下の場合のみ、処理を続ける
if tmp <= N:
# 立方数が回文であるかをチェック(文字列に変換して逆順と比較)
if str(tmp) == str(tmp)[::-1]:
# 条件を満たす場合は、最大の回文立方数を更新
ans = tmp
else:
# 計算した立方数がNを超えた場合、ループを終了
break
# 見つかった最大の回文立方数を出力
print(ans)
解答
# 入力
N = int(input())
# 回文立方数を格納する変数
ans = 1
# 10**7までの数でループを実行
for i in range(10**7):
# 立方数を計算
tmp = i**3
# 計算した立方数がN以下の場合のみ、処理を続ける
if tmp <= N:
# 立方数が回文であるかをチェック(文字列に変換して逆順と比較)
if str(tmp) == str(tmp)[::-1]:
# 条件を満たす場合は、最大の回文立方数を更新
ans = tmp
else:
# 計算した立方数がNを超えた場合、ループを終了
break
# 見つかった最大の回文立方数を出力
print(ans)
ABC343 D – Diversity of Scores
問題
解説
各選手の得点、各得点に対する人数、異なる得点の種類の数を管理して、得点の変動がある度に更新を行う。
解説
collections.defaultdict
をimportします。
from collections import defaultdict
N
とT
を入力から受け取ります。
# 入力
N, T = map(int, input().split())
配列score
を使用して、各選手の得点を管理します。
# 各選手の得点を初期化
score = [0] * (N + 1)
defaultdict(int)
を使用して、d
辞書を初期化します。これは、特定の得点を持つ参加者の数を保持します。初期状態では、すべての参加者が得点0
を持つため、d[0] = N
と設定します。
# defaultdictを使用して、各得点に対する人数を管理
d = defaultdict(int)
# 得点0を持つ人数をNとして初期化
d[0] = N
変数kind
は異なる得点の種類の数を管理します。初期状態では、全員が得点0
を持っているため、1
に設定されます。
# 異なる得点の種類の数を管理する変数
kind = 1
T
回の操作に対してループを実行します。各操作では、選手a
の得点にb
を加算します。
# T回の操作を実行する
for _ in range(T):
# 入力
a, b = map(int, input().split())
得点更新前に、選手a
の現在の得点を持つ選手がa
だけであれば、kind
を減らします。
# aの現在の得点が1人だけであれば、種類の数を減らす
if d[score[a]] == 1:
kind -= 1
選手a
の現在の得点を持つ人数を1減らします。
# aの現在の得点を持つ人数を1減らす
d[score[a]] -= 1
選手a
の得点を更新します。
# aの得点を更新する
score[a] += b
得点更新後にその得点を持つ選手がいなかった場合、新しい得点の種類が追加されるため、kind
を増やします。
# 更新後の得点を持つ人がいない場合は、種類の数を増やす
if d[score[a]] == 0:
kind += 1
更新後の得点を持つ選手の数を1増やします。
# 更新後の得点を持つ参加者の数を1増やす
d[score[a]] += 1
最後に、異なる得点の種類の数kind
を出力します。
# 現在の異なる得点の種類の数を出力する
print(kind)
解答
from collections import defaultdict
# 入力
N, T = map(int, input().split())
# 各選手の得点を初期化
score = [0] * (N + 1)
# defaultdictを使用して、各得点に対する人数を管理
d = defaultdict(int)
# 得点0を持つ人数をNとして初期化
d[0] = N
# 異なる得点の種類の数を管理する変数
kind = 1
# T回の操作を実行する
for _ in range(T):
# 入力
a, b = map(int, input().split())
# aの現在の得点が1人だけであれば、種類の数を減らす
if d[score[a]] == 1:
kind -= 1
# aの現在の得点を持つ人数を1減らす
d[score[a]] -= 1
# aの得点を更新する
score[a] += b
# 更新後の得点を持つ人がいない場合は、種類の数を増やす
if d[score[a]] == 0:
kind += 1
# 更新後の得点を持つ参加者の数を1増やす
d[score[a]] += 1
# 現在の異なる得点の種類の数を出力する
print(kind)
ABC343 E – 7x7x7
問題
解説
3つの立方体の可能な配置を探索し、その配置が存在するかどうかを判定する。
解説
1つ目の立方体は平行移動して(a1, b1, c1)=(0, 0, 0)
としてよい。
2つ目の立方体は回転や鏡像を取ることで \(0 \le a_2 \le b_2 \le c_2\) と考えても良いです。
また、2つ目、3つ目の立方体は共通部分を持たない場合は平行移動することで1
つ目の立方体と接する位置まで動かすことができます。
以上の3つから考えられる位置を全探索します。
解答
# 2つの立方体の重なる体積を計算する関数
def calculate_2overlap_volume(a1, b1, c1, a2, b2, c2):
# X軸に沿った重なりの長さを計算
overlap_x = max(0, min(a1 + 7, a2 + 7) - max(a1, a2))
# Y軸に沿った重なりの長さを計算
overlap_y = max(0, min(b1 + 7, b2 + 7) - max(b1, b2))
# Z軸に沿った重なりの長さを計算
overlap_z = max(0, min(c1 + 7, c2 + 7) - max(c1, c2))
# 重なる体積を返す
return overlap_x * overlap_y * overlap_z
# 3つの立方体の重なる体積を計算する関数
def calculate_3overlap_volume(a1, b1, c1, a2, b2, c2, a3, b3, c3):
# X軸に沿った重なりの長さを計算
overlap_x = max(0, min(a1 + 7, a2 + 7, a3 + 7) - max(a1, a2, a3))
# Y軸に沿った重なりの長さを計算
overlap_y = max(0, min(b1 + 7, b2 + 7, b3 + 7) - max(b1, b2, b3))
# Z軸に沿った重なりの長さを計算
overlap_z = max(0, min(c1 + 7, c2 + 7, c3 + 7) - max(c1, c2, c3))
# 重なる体積を返す
return overlap_x * overlap_y * overlap_z
# 入力
a, b, c = map(int, input().split())
# 3つの立方体の合計体積が3倍の7x7x7でなければ"No"を出力
if a + 2 * b + 3 * c != 3 * 7 * 7 * 7:
print('No')
exit()
else:
# 立方体の位置を変えて配置を探索
for a2 in range(0, 8):
for b2 in range(a2, 8):
for c2 in range(b2, 8):
for a3 in range(-7, 8):
for b3 in range(-7, 8):
for c3 in range(-7, 8):
# 3つの立方体の重なる体積を計算
v3_overlap_total = calculate_3overlap_volume(0, 0, 0, a2, b2, c2, a3, b3, c3)
if v3_overlap_total != c:
continue
# 2つの立方体の重なる体積の合計を計算
v2_overlap_total = calculate_2overlap_volume(0, 0, 0, a2, b2, c2) + \
calculate_2overlap_volume(a2, b2, c2, a3, b3, c3) + \
calculate_2overlap_volume(0, 0, 0, a3, b3, c3) - \
3 * v3_overlap_total
if v2_overlap_total != b:
continue
# 条件を満たす配置が見つかれば"Yes"と配置を出力
print('Yes')
print(0, 0, 0, a2, b2, c2, a3, b3, c3)
exit()
# 条件を満たす配置が見つからなければ"No"を出力
print('No')