C++倒计时游戏

方法1(模拟方法):

# 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

}