結果
| 問題 | No.78 クジ付きアイスバー |
| コンテスト | |
| ユーザー |
le_panda_noir
|
| 提出日時 | 2020-07-25 12:07:21 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 5,000 ms |
| コード長 | 1,702 bytes |
| 記録 | |
| コンパイル時間 | 890 ms |
| コンパイル使用メモリ | 85,496 KB |
| 最終ジャッジ日時 | 2025-01-12 05:24:29 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 35 |
ソースコード
#include <iostream>
#include <numeric>
#include <vector>
#include <set>
using namespace std;
#define rep(i,n) for(int i=0,_i=(n);i<_i;++i)
#define all(f,_v,...)(([&](decltype((_v)) v){return(f)(begin(v),end(v),##__VA_ARGS__);})(_v))
int main() {
int N, K; cin >> N >> K;
string S; cin >> S;
vector<int> G(N, 0);
rep(i, N) {
int atari = S[i] - '0', j = 0;
while (atari > 0) {
--atari;
++j;
atari += S[(i+j)%N] - '0';
if (j > N)
break;
}
G[i] = (j > N ? N : (i+j+1)%N);
}
if (G[0] == N) {
cout << 1 << endl;
return 0;
}
set<int> st;
vector<pair<int, int>> v;
int cur = 0, next = G[0], ans = 0;
for (; st.find(cur) == st.end(); cur = next, next = G[cur]) {
// サイクルを見つけるまですすめる
++ans;
if (next == N) {
// 無限に手に入る地点に来た
cout << ans << endl;
return 0;
}
int distance = (next > cur ? next - cur : N + next - cur);
K -= distance;
if (K <= 0) {
// サイクルを見つけるまえにKが0になったので終了
cout << ans << endl;
return 0;
}
v.emplace_back(cur, distance);
st.insert(cur);
}
vector<int> circle;
rep(i, v.size()) {
if (v[i].first != cur)
continue;
// i = サイクルのスタート地点
// サイクルを取得する
while (i < (int)v.size())
circle.push_back(v[i++].second);
break;
}
// サイクルを利用して計算
int sum = all(accumulate, circle, 0);
ans += (K / sum) * circle.size();
K %= sum;
rep(i, circle.size()) {
if (K <= 0)
break;
K -= circle[i];
++ans;
}
cout << ans << endl;
return 0;
}
le_panda_noir