ABC220 C - Long Sequence C++解答例
AtCoder Beginner Contest 220のC問題をC++で解きます。
問題
問題文をAtCoderのページより引用します。
問題文
長さ
の正整数のみからなる数列 N があります。 A = (A_1, \ldots, A_N)
を A 回連結した数列を数列 10^{100} とします。 B Bの項を前から順に足したとき、和が初めて
を超えるのは何項目まで足したときですか? X
すなわち、以下の式を満たす最小の整数を求めてください。 k
\sum_{i = 1}^{k} B_{i} > X
制約
1 \leq N \leq 10^5 1 \leq A_{i} \leq 10^9 1 \leq X \leq 10^{18} - 入力は全て整数
解答例
考え方
愚直に考えるとTLE
数列
B の定義からヒントを得る
数列
これを踏まえると、「
これを拡張して考えてみます。求める項
定義より、この数列
ということは、この
では実際に
数列
また、
従って、
次に
この問題を解くために探索しなければならない範囲は数列
以上で
プログラムを実装してみる
以上の考え方を実装したのが以下のコードです。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
int main() {
int64_t N;
std::cin >> N;
std::vector<int64_t> A(N);
for (int64_t i = 0; i < N; i++) {
std::cin >> A.at(i);
}
int64_t X;
std::cin >> X;
// 数列Aの総和
int64_t sum = std::accumulate(A.begin(), A.end(), static_cast<int64_t>(0));
// XをAの総和で割った商
int64_t quotient = X / sum;
// XをAの総和で割った余り
int64_t residue = X % sum;
// 数列Aの各要素を先頭から足していったときの和
int64_t total = 0;
// 和が初めてrを超えたときの項
int64_t index = 0;
for (int64_t i = 0; i < N; i++) {
total += A.at(i);
index = i + 1;
if (total > residue) {
break;
}
}
std::cout << index + quotient * N << std::endl;
return 0;
}
実際に提出したコードはこちら。
Discussion