题目描述:
设有n个人围坐一圈并按顺时针方向从1到n编号,从第1个人开始进行1到m的报数,
报数到第个m人,此人出圈,再从他的下一个人重新开始1到m的报数,如此进行下去直到所剩下一人为止。
输入多行,每行2个数,分别表示n和m.
输出每一行中最后剩下这个人的编号.
样例输入
10 3
样例输出
4
解题思路:
首先大家要搞明白这道题在草稿纸上的运算过程,假设有 n = 10个人坐在一起,按顺序从1-10开始编号,m = 3,刚开始我们先引入一个变量 num=0。
第一步,访问到编号为1的这个人,此时 num = 0 + 1 = 1,num != 3,
第二步,访问编号为2的这个人,此时 num = 1 + 1 = 2, num != 3,
第三步,访问编号为3的这个人,注意!此时 num = 2 + 1 = 3,发现 num == 3,那么我们就需要把编号为3的这个人剔除,这里为了方便,我们可以让他的编号变成 0 ,同时,我们需要让 num 这个变量从3 变成 0 ,可能很多小伙伴不知道这是什么意思,大家想一下,我们在草稿纸上画的时候遇到num = 3 时是不是就说明这个数已经被找到了一个,那么num 是不是就要开始重新计数,因为这样才可以找出其他报 3 也就是( m )的人。
接下来重复着几个步骤,发现在第一轮中,大家一共比较了 n 次,把编号为 3 ,6,9 数字给剔除出去了(也就是让他们变为了 0 )
在第一回合中,大家比较了 n 次,第二回合中,由于第一回合大家剔除了 3 个数字,所以第二回合就只需要比较 ( n - 3 )个数字就可以了。这里我们就需要一个while循环,作用是当数组里面只有 1 个数字时,那么就停止比较,输出结果。
以下是代码:
#include<iostream>
using namespace std;
void Compare(int n1,int n2)
{
while(n1!=0&&n2!=1) //n2是不能等于1的
{
int a[n1],b=n1,c=0;
for(int i=0;i<n1;i++)
a[i] = i+1; //给a[i]赋值
while(b>1) //b代表了需要比较数字的个数,当等于1时就跳出循环
{
for(int i=0;i<n1;i++)
{
//当a[i]不等于0时,那么计数器就加1
if(a[i]!=0)
c++;
//当c==n2时,就把a[i]变为0,同时计数器恢复为0,那么需要比较的数字也就减1
if(c==n2)
{
a[i] = 0;
c=0;
--b;
}
/*
这里大家一定要注意两个if的书写顺序,因为一上来大家是先把数组中的数字和0比较,
如果是0,那么就跳过,如果不是0,那么 c 就 +1,然后再把 c 和 n2 进行比较。并不是一上来就
把 c 和 n2 比的,我之前以为反正两个 if 都是做判断的顺序无所谓,但事实证明我这个想法错的很离谱!
*/
}
}
for(int i=0;i<n1;i++)
if(a[i]!=0)
cout<<a[i]<<endl;
cin>>n1>>n2;
}
}
int main()
{
int num1,num2;
cin>>num1>>num2;
Compare(num1,num2);
return 0;
}
如果有什么地方是大家觉得不足的,欢迎大家前来指出!