#include<bits/stdc++.h>
#include<vector>
#include<algorithm>
using namespace std;
void safe(int n,int k,int a[])
{
vector<int>s(a+0,a+n);
vector<int>b(a+0,a+n);
while(s.size()>1)
{
int r;
r=s.size();
int count=1;
while(count<=r)
{
b[count%r]=0;
count=count+k;
}
b.erase(remove(b.begin(),b.end(),0),b.end());
s=b;
}
for(int x:s)
{
cout<<x<<"n";
}
}
int main()
{
int t;
cin>>t;
for(int i=0;i<t;i++)
{
int n,k;
cin>>n>>k;
int *a=new int[n];
for(int j=1;j<=n;j++)
{
a[j-1]=j;
}
if(n>2)
{
safe(n,k,a);
}
else if(n==2)
{
cout<<a[1]<<"n";
}
else
cout<<a[0]<<"n";
}
}
输入:
4
4 2
5 2
2 1
50 10
输出:
1
3
2
19 --> it should be 36
如果你不知道这个问题问题描述:有n个人站在一个圆圈里(顺时针从1到n(等待处决。计数从圆中的点1开始,并沿固定方向(顺时针(绕圆进行。在每一步中,都会跳过一定数量的人,然后执行下一个人。清除工作围绕着这个圆圈进行(随着被处决的人被清除,这个圆圈越来越小(,直到只剩下最后一个人,他得到了自由。给定总人数n和数字k,该数字表示跳过了k-1人并且在圆圈中杀死了第k人。任务是在最初的圆圈中选择一个位置,这样你就可以成为最后一个剩下的人,从而生存下来。考虑如果n=5和k=2,则安全位置为3。首先,位置2的人被杀,然后位置4的人被杀死,然后位置1的人被打死。最后,5号位置的人被杀。所以3号位的人活了下来。
这里有一个可能的解决方案,希望注释能说明清楚。不需要分配int[]
并将其复制到向量中,可以直接使用iota
初始化向量。同样,您可以在执行过程中删除元素,而不是在以后的步骤中进行归零和删除。
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
using namespace std;
void safe(int n, int k) {
vector<int> s(n);
// Init the vector 1..n
iota(s.begin(), s.end(), 1);
int i = 0;
// While more than one survive...
while (s.size() > 1) {
// Skip forward (k-1)
i = (i + k - 1) % s.size();
// Kill the next one
s.erase(s.begin() + i);
}
for (int x : s) {
cout << x << "n";
}
}
int main() {
int t;
cin >> t;
for (int i = 0; i < t; i++) {
int n, k;
cin >> n >> k;
if (n > 2) {
safe(n, k);
} else if (n == 2) {
cout << 2 << "n";
} else
cout << 1 << "n";
}
}