洛谷P2696题解
[传送锚点](P2696 慈善的约瑟夫 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))
比不过大佬,从蒟蒻做起
选择比较水有意思的解法——用队列模拟(还是窝太弱了)
正片开始
考虑队列模拟,因为每次都是假的剔除,所以我们的目标是找到每回游戏的最终存活者。
将不被剔除,即每次编号求余2结果为1的人再次扔进队列里,直到队列长度为一,最后剩下的就是最终幸存者。
ll del(ll x)
{
for(int i=1;i<=x;i++) q.push(i);
int f=1;
while(q.size()!=1)
{
int u=q.front();q.pop();
if(f%2==1) q.push(u),f++;
else f++;
}
int ans=q.front();
q.pop();
return ans;
}
接下来就可以开始快乐的处理答案了。
直接干while循环,直到最终幸存者(记为s)是序列的最后一人,对于每次剔除的人n-s,将ans+=n-s。结束循环前,将最后剩余的s人乘上2加到ans里即可。
完整代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
queue<int>q;
ll del(ll x)
{
for(int i=1;i<=x;i++) q.push(i);
int f=1;
while(q.size()!=1)
{
int u=q.front();q.pop();
if(f%2==1) q.push(u),f++;
else f++;
}
int ans=q.front();
q.pop();
return ans;
}
int n,ans;
int main()
{
cin>>n;
while(1)
{
int s=del(n);
if(s==n)
{
ans+=2*s;
break;
}
ans+=n-s;
n=s;
}
cout<<ans<<endl;
return 0;
}
本蒟蒻实力有限,如有错误还请各位大佬指出。