N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人重新从1开始报数。问最后剩下的人的编号。
例如:N = 3,K = 2。2号先出列,然后是1号,最后剩下的是3号。
输入
2个数N和K,表示N个人,数到K出列。(2 <= N, K <= 10^6)
输出
最后剩下的人的编号
输入样例
3 2
输出样例
3
简单模拟
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int a[1000];
int n,k,j=0,bk=0;
cin>>n>>k;
for(int i=0;i<n;i++)
a[i]=i+1;
while(j!=n-1){
for(int i=0;i<n;i++){
if(a[i] == 0) continue;
bk++;
if(bk != k) continue;
bk=0;
a[i]=0;
j++;
if(j == n-1) break;
}
}
for(int i=0;i<n;i++)
if(a[i] ) cout<<a[i];
}
数学递推公式
int cir(int n,int m)
{
int p=0;
for(int i=2;i<=n;i++)
{
p=(p+m)%i;
}
return p+1;
}
数学递推公式的做法比较好,虽然时间复杂度低,简易但是不大好理解,
我感觉讲的比较好的
============================ 3.27
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=100000;
int people[maxn] , result[maxn];
int main(){
int n,count=0,start=0,m;
cin >> n >> m;
for(int i = 0 ;i < n ; i++){
people[i]=i;
}
for(int j = n ; j > 1 ; j--){
start=(start + m - 1) % j ;
result[count++] = people[start];
for(int k =start + 1 ; k < j ; k++){
people[k - 1] = people[k];
}
}
result[count++]= people[0];
for(int i=0;i<count;i++)
cout<<result[count-1]<<' ';
return 0;
}
添加一个做法,以前知道有这种做法,但是不大会打,这种我还有一种疑问,为什么直接打people[0] 打不出来= =,
-----------------4.17
更新一个队列的做法和用vector做的,都是简单模拟
#include<iostream>
#include<queue>
using namespace std;
queue<int> q;
int main(){
int m,n,bk=1;
cin>>n>>m;
for(int i=1;i<=n;i++)
q.push(i);
while(!q.empty()){
if(bk!=m){
q.push(q.front());
q.pop();
bk++;
}
else{
cout<<q.front()<<' ';
q.pop();
bk=1;
}
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
vector<int> v;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) v.push_back(i);
int vz=0;
while(v.size()>1)//当数组内有数时,做循环、
{
vz=(vz+m-1)%v.size();
cout<<v[vz]<<' ';
v.erase(v.begin()+vz);
}
cout<<v[0]<<endl;
return 0;
}