题目如下:
猴子选大王,办法如下:猴子按1,2…n编号围坐一圈,从第一只开始按1,2,…m报数,报m的退出,从下一只开始,继续循环报数,剩下的最后一只猴子就是大王,编程输出大王的序号。
input:输入仅一行,输入猴子个数n和报数m。
output:输出仅一行,输出大王的序号。
sample input:10 3
sample output:4
这个题目看上去比较复杂,但如果我们选择一个好的思路就会感觉到很容易。首先我们可以把每只猴子依次放入一个数组里,把它们都定为0,这个0代表着它们还没出局,具有被选举权。每一次报数被选中后,可以赋值一个1,代表已经被出局了,这样构成一个循环体,跳出条件是最后只剩一个数字是0的猴子。这样就显得尤为简单。
用C语言实现如下:
#include<stdio.h>
int a[501]; //定义全局变量的数组,会自动给数组元素赋上0
int main()
{
int n, m, out=0, num=0, i=1; //out为出局的猴子
scanf("%d%d",&n,&m);
while(out!=n-1) //剩余最后一只猴子结束循环
{
if(a[i]==0)
num++;
if(num==m)
{
num=0; //num重新计数
a[i]=1;
out++;
}
i++;
if(i==n+1) //最后一个猴子计数完重新计数
i=1;
}
for(i=1; i<=n; i++)
{
if(a[i]==0)
{
printf("%d",i);
break;
}
}
return 0;
}
这是常规思路,如果我们了解过一些算法的话,会发现它是一道典型的约瑟夫环的问题。
#include <stdio.h>
int ysfdg(int a,int b,int c);
int main()
{
int n, m;
scanf("%d%d", &n, &m);
printf("%d", ysfdg(n,m,n)+1);
}
int ysfdg(int a,int b,int c)
{
if(c==1)
return (a+b-1)%a;
else
return ((ysfdg(a-1,b,c-1)+b)%a);
}
上面就是用约瑟夫递归的解法,看上去就简洁明了了许多,不过理解起来比较困难。
当有了一个好的算法后,一个复杂的题目也会变得容易很多。