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

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

AtCoder-ABC220 C - Long Sequence【Python解答例】

AtCoder Beginner Contest220のC問題についてPythonの解答例を記事にしていきます。
AtCoder Beginner Contest 220 - AtCoder



AtCoder Beginner Contest220 C - Long Sequence

C - Long Sequence

問題文

長さ N の正整数のみからなる数列 A=(A 1​ ,…,A N​ ) があります。
A を 10 ^ 100 回連結した数列を数列 B とします。

B の項を前から順に足したとき、和が初めて X を超えるのは何項目まで足したときですか?
すなわち、以下の式を満たす最小の整数 k を求めてください。

i=1
∑ ​ B i​ >X
k

制約

・1≤N≤10 ^5
・1≤A i​ ≤10 ^9
・1≤X≤10 ^18
・入力は全て整数

解答例

n = int(input())

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

x = int(input())

sum_a = 0
for i in range(n):
    sum_a += A[i]

ans = 0
ans += n * (x // sum_a)
SUM = sum_a * (x // sum_a)
i = 0
while x >= SUM:
    SUM += A[i]
    ans += 1
    i += 1

print(ans)

解説

数列Aの10^100回連結した数列Bの項を左から順に足していき、その和がXを超えるのが何項目か答える問題です。

1項ずつ最初から順番に足していくとTLEになりますので、数列Aの総和sum_aを求めて計算量を少なくしました。

答えとなる項数をansと置き、Xをsum_aで割った商にNをかけた値を代入します。
もとめる項数ansはこの値から数列Aの項数以下の範囲にあることになります。

数列Bを左から足していった総和SUMも数列Aの総和sum_aにXをsum_aで割った商をかけた値なので同時に計算しておきました。

あとはSUMがXを超えるまでwhile文でSUMに項を足し続けます。
足すたびにansに1を足し、SUMがXを超えたときのansを出力すればOKでした。


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