ABC281(C問題) 感想
本日はABC281のC問題について。
以下が私が最初に書いたコード。まずこれはセグフォで通らなかった。理由としては、ベクトルの要素数を定義していないのに関わらずA[i]のようにベクトル要素にアクセスしてしまっているからである。そこでstd::vector<int> A(N)
のように要素数を決めてしまうのが良い。ただ、今回は新しく配列に要素を追加するというようなことがないので、ただの配列を用いるだけの方がスマートだった気がする。
#include <iostream> #include <vector> using namespace std; int main() { int N, T; cin >> N >> T; std::vector<int> A; int total_time = 0; for (int i = 0; i < N; ++i) { cin >> A[i]; } for (int i = 0; i < N; ++i) { total_time += A[i]; } cout << A[0] << endl; int tmp = total_time % T; int song_num = 0; int time_from_start = 0; for (int i = 1; i <= N; ++i) { if (A[i-1] > tmp) { song_num = i; time_from_start = tmp; break; } tmp -= A[i-1]; } cout << song_num << " " << time_from_start << endl; return 0; }
ただベクトルの要素数を決めただけだと通らなかった。そこでこの似たような間違いをした人がどのように修正してACしたかを教えてくれる素晴らしいサイト(https://atcoder-companions.kakira.dev/)を用いて自分の解答を分析した。するとどうやら型の問題で、intとしているのがおかしいみたい。実際問題のそれぞれの整数の範囲を確認する。すると1≤A[i]≤109, 1≤T≤1018 という条件を確認することができる。int型は32bitで、大体2*109程度までを符号付きで表せるだけであるので、オーバーフローしてしまう。そこで、Tを64 bitのlong long型にしてあげる必要がある。そうして見事以下のコードでACした(以下ではA[i]もlong long型にしているが本来そうする必要ない)。
#include <iostream> #include <vector> using namespace std; using ll = long long; int main() { ll N, T; cin >> N >> T; std::vector<ll> A(N); ll total_time = 0; for (int i = 0; i < N; ++i) { cin >> A[i]; total_time += A[i]; } ll tmp = T % total_time; ll song_num = 0; ll time_from_start = 0; for (int i = 1; i <= N; ++i) { if (A[i-1] > tmp) { song_num = i; time_from_start = tmp; break; } tmp -= A[i-1]; } cout << song_num << " " << time_from_start << endl; return 0; }