C++倒计时游戏
# include & ltiostream & gt
使用?STD::CIN;
使用?STD::cout;
int?主()
{
int?n,m;
cout & lt& lt“请输入n=?”;
CIN & gt;& gtn;
如果(n & lt1)
{
cout & lt& lt" n必须大于1!\ n请重新输入n=?;
CIN & gt;& gtn;
}
cout & lt& lt“请输入m=?”;
CIN & gt;& gtm;
布尔?*?答?=?新的?布尔?[n+1];
a[0]=假;
for(int?I = 1;我& ltn+1;i++)
a[I]=真;
int?x,k = n;x = I = 0;//i是每个周期的计数变量,X是人员序号,K是剩余人数。
而(k!=0)
{
x++;
if(x & gt;n)?x = 1;//当person到达数组末尾时,序列号被重置为1。
if(a[x])i++;?//?跳过已经退出的人。
如果(i==m)
{ a[x]= false;I = 0;k-;}//计数到m时,退出人数设置为false,剩余人数减1,I设置为0,重新计数。
}
cout & lt& lt“留下来的人的序列号是:?”& lt& ltx & lt& lt”\ n”;
删除?[]?a;
CIN . get();
CIN . get();//等待下一次击键关闭窗口。
回归?0;
}
方法2(递归方法):
这个问题可以用数学方法解决。
有n人(编号为0~(n-1)),从0开始计数,报(m-1)时退出,其余继续从0开始计数(数学求解时要注意从0开始编号,因为余数会得到0解。)
本质上是一种递归,N中留守人员的序号和n-1中留守人员的序号之间存在递归关系。
假设第k个人被移除,那么
0,1,2,3, ...,k-2,k-1,k,...,n-1//原始序列(1)
0, 1, 2, 3, ...,k-2,?,k,...,n-1?//去掉第k个人,也就是去掉序号k-1的人?(2)
K,K+1,...,N-1,0,1...,K-2//从序列号K开始,报0?(3)
0, 1, ...,n-k-1,n-k,n-k+1,...,n-2?//数量转换,此时队列为n-1人(4)
改造后完全变成(n-1)个人号的子问题。注意,(1)和(4)是同一个问题,区别只是人数。对比(4)和(3)不难看出,0+k=k,1+k=k+1,...(3)中“0”之后的数字,
((n-3)+k)%n=k-3,((n-2)+k)%n=k-2。对于公式(3)中' 0 '之前的数,由于小于n,也可以看作是(0+k)%n=k,(1+k)%n=k+1,?因此,可以得出这样的规律:
设(3)中的一个数为x’,对应的(4)中的数为x,则有:x’=(x+k)% n .
当X是最后剩下的人数时,当队列只剩下1人时,显然X = 0;这时候你可以回到2人时X对应的序号,3人时X对应的序号……直到n人时X的序号,这就是你想要的。
#包含?& ltiostream & gt
使用?命名空间?std
int?主()
{
int?n,m,f = 0;
CIN & gt;& gtn & gt& gtm;
for(int?I = 2;我& lt= n;i++)?
f =(f+m)% I;
cout & lt& ltf+1 & lt;& ltendl
}