n个数字(1,2,3…,n)形成一个圆圈,从数字1开始,每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。
当一个数字删除后,从被删除数 字的下一个继续删除第m个数字。
求出在这个圆圈中剩下的最后一个数字。
Input
n=9
m=5
Output
The last one is 8
解题思路:
利用队列是线性的关系,将m之前的数重新排入队尾,而第m个则被删除
1 #include<stdio.h> 2 #include<queue> 3 using namespace std; 4 int main() 5 { 6 queue<int>q; 7 int n,m,i,a; 8 scanf("%d%d",&n,&m); 9 for(i=1; i<=n; i++) 10 { 11 q.push(i);///入队 12 } 13 while(q.size()>1)///1为最后剩下的人数 14 { 15 for(i=0;i<m;i++) 16 { 17 a=q.front();///返回首元素 18 q.pop();///删除首元素 19 if(i<m-1) 20 { 21 q.push(a);///压入队尾 22 } 23 } 24 } 25 printf("%d ",q.front()); 26 return 0; 27 }
另外附上当时使用虚拟数组来实现的约瑟夫环的代码:
#include<stdio.h> int main() { int n,m,i,j,a[10000],count; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1; i<=n; i++) { a[i]=i; } j=n;///j圈中剩余人数 count=0; i=1;///从1开始报数 while(j>1)///只剩下一个人为止 { if(a[i]!=0) { count++; if(count==m)///报道数 { a[i]=0;///退出圈子 count=0;///清零重新从1开始报数 j--;///剩余人数减一 } } i++;///下一个人准备报数 if(i>n)///若越过最后一人 i=1;///转到第一人 } for(i=1; i<=n; i++) { if(a[i]!=0) printf("%d ",a[i]); } } return 0; }