问题原型:
有 n个人围成一圈,顺序排号。从第一个人开始报数(从 1到 3报数),凡报到 3的 人退出圈子,问最后留下的是原来第几号的那位。
n<1000
实质:
约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。又称“丢手绢问题”.)
使用数组,用01标记是否在队列中,0是退出队列,1是在队列中。
#include<iostream>
using namespace std;
int find(int n) // 传入人数
{
/*
数组存放人数,元素0/1表示是否退出队列
i是下标,count 表示剩下的人数
flag 标志位,flag==3表示退出队列
*/
int a[1000], i, count, flag=0;
count=n; // 初始状态为n人
for (i=1; i<=n; i++)
a[i]=1;//所有人都在圈内,为1
for (i=1; ;i++) // 从1-n增长,如果i>n从1重新排序
{
if (i==n+1)
i=1;//如果i超出了n个人,让他重新回到1
if (a[i]!=0) // 如果人在圈内
flag++; // 报数加1
else
continue;
if (flag%3==0)
{
a[i]=0; // 退圈
count--;// 人数--
}
if (count==1)//表示只剩下一个人在圈内
break;
}
for (i=1; i<=n; i++) // 找到元素为1的下标即为开始的位置
if (a[i]!=0)
count = i;//注意这里是输出i,一开始写的a[i],调试了老半天
return count;
}
int main()
{
int n;
cin>>n;
n = find(n);
cout<<n<<endl;;
return 0;
}