注意力惊人
xiaoyi_zeng · · 题解
B4395
哇塞,可以写题解。
打表找规律
首先你需要一份打表代码。
:::info[打表代码]
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
vector <int> v;
int main(){
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i ++ ) v.push_back(i);
while (v.size()){
cout << v[0] << " ";
vector <int> t;
for (int i = 0; i < v.size(); i ++){
if (i % k == 0) continue;
t.push_back(v[i]);
}
v = t;
}
cout << "\n";
}
:::
嗯对,在这里 30 已经足够大了。
请不要试图输入
注意力惊人
正片开始。
首先,上面的代码所输出的是每一轮删除的第一个数。
注意到题目中没有说如果最后一轮淘汰了所有人怎么办,所以最后一轮之后肯定只剩下一个人。
注意到这一个人一定是最后输出的那个数字。
注意到如果令程序输出的第
代码编写
如果你直接写,那恭喜你成为 @KingGojianOfYue 大佬的 Hack 对象。
考虑维护长度为
如果
可以证明,这样做的时间复杂度不会超过
你可能会问,这不是
实则不然,仔细一想,当
Code
:::success[AC code]
#include <bits/stdc++.h>
using namespace std;
long long n, k;
int main(){
cin >> n >> k;
long long x = 1, lst = 0;
while (x <= n){
long long id = (x - 1) / (k - 1) + 1;
long long end = min(n, id * (k - 1));
x = (x + ((end - x) / id + 1) * id);
lst = x - id;
}
cout << lst << "\n";
}
:::