ebisukeプログラミング初心者脱出黙示録

30歳を過ぎてから始めたプログラミングと競プロの記録。Pythonで取り組んでいます。Arduinoで電子工作も

京セラプログラミングコンテスト2021 C - Ringo's Favorite Numbers 2【Python解答例】

f:id:ebisuke33:20210508234453p:plain

京セラプログラミングコンテスト2021(AtCoder Beginner Contest200)のC問題についてPythonの解答例を記事にしていきます。
KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) - AtCoder


AtCoder Beginner Contest200 C - Ringo's Favorite Numbers 2

C - Ringo's Favorite Numbers 2

問題文

200 という整数が大好きなりんごさんのために、次の問題を解いてください。
N 個の正整数からなる数列 A が与えられるので、以下の条件をすべて満たす整数の組 (i , j) の個数を求めてください。

・1 ≤ i < j ≤N
・Ai − Aj は 200 の倍数である。

制約

・入力は全て整数
・2 ≤ N ≤ 2×10^5
・1 ≤ Ai ≤ 10^9

解答例

n = int(input())

A = list(map(int, input().split()))

# Aiを200で割った余りの個数リスト
lis = [0 for _ in range(200)]

# Aiを200で割った余りの個数をリストにメモ
for i in range(n):
    tmp = A[i] % 200
    lis[tmp] += 1

# 求める場合の数を余りの個数ごとに計算
ans = 0
for j in range(200):
    num = lis[j] - 1
    if num > 0:
        ans += num * (num + 1) // 2

print(ans)

解説

素数がN個の数列Aで問題文の条件を満たす整数の組の個数を求める問題です。

Ai - Aj が200の倍数であることは、Aiを200で割った余りとAjを200で割った余りが同じであればよいです。
数列Aの各要素を200で割った余りkの個数を管理するためリストlisを作成しました。

次のfor文では数列Aの各要素を200で割り、余りkに応じてlis[k]の値に1を足しました。
ループを抜ければ各余りkの個数がわかるようになります。

最後に、AiとAjを200で割った余りがk個の場合、条件を満たす整数の組はk×(k-1)/2となります。
この整数の組をすべての余りに対して求めることで、解答となる整数の組を求めることができました。



ABC200の関連記事はこちら
ebisuke33.hatenablog.com