【AtCoder】ABC343解説(Python)

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

NTを入力から受け取ります。

# 入力
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')
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次