一座山周围有n个洞,顺时针编号为0,1,2,..., n-1。一只狼从0号洞开始,顺时针方向计数,每当经过第m个洞时,就进洞找兔子。例如n=5, m=3,狼经过的洞依次为0,3,1,4,2,0。输入m,n。试问兔子有没有幸免的机会?如果有该藏在哪儿?
分析:若n=6, m=3,则狼经过的洞依次为0,3,0,兔子有幸免机会,应藏在1,2,4,5号洞中的一个洞即可。
若n=6,m=5, 则狼经过的洞依次为0,5,4,3, 2, 1, 兔子没有幸免机会。
当n和m的最大公约数大于1时,兔子有幸免机会。兔子可藏在所有编号与n互素的洞中。
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
//该程序求解最大公约数那块有点问题
//方案一
int gcd(int n, int m) //求m和n的最大公因数
{
int k=n>=m? n:m, s=n<m?n:m, r;
if (s==0) return k;
r=k%s;
while (r)
{
k=s;
s=r;
r=k%s;
}
//printf("m和n的最大公约数为 %d\n", s);
return s;
}
void escape1(int n, int m )
{
int a[n]= {0}, i=m, j=2;
int r=gcd(n, m);
//printf("$$$ m和n的最大公约数为 %d\n", r);
if (r==1)
{
printf("兔子没有幸免的机会!\n");
return;
}
printf("兔子有幸免机会,可以藏在以下编号的洞:");
for (int j=0; j<n; j++) //编号为非r的倍数的洞都可藏兔子
if((j%r)!=0)
printf("%d ", j);
printf("\n");
}
//方案二
void escape(int n, int m )
{
int a[n]= {0}, i=m, count=0;
for (int j=0; j<n; j++)
a[j]=1;
a[i]=0;
while (i!=0)
{
i=(i+m)%n;
a[i]=0;
}
a[i]=0;
for (int i=0; i<n; i++)
if (a[i])
count++;
if (count==0)
printf("兔子没有幸免的机会!\n");
else
{
printf("兔子有幸免机会,可以藏在以下编号的洞:");
for (int i=0; i<n; i++)
if (a[i])
printf("%d ", i);
}
printf("\n");
}
int main()
{
escape1(9, 3);
escape(9, 3);
escape1(5, 3);
escape(5, 3);
escape1(9, 6);
escape(9, 6);
//system("pause");
//return 0;
}
运行结果:
兔子有幸免机会,可以藏在以下编号的洞:1 2 4 5 7 8
兔子有幸免机会,可以藏在以下编号的洞:1 2 4 5 7 8
兔子没有幸免的机会!
兔子没有幸免的机会!
兔子有幸免机会,可以藏在以下编号的洞:1 2 4 5 7 8
兔子有幸免机会,可以藏在以下编号的洞:1 2 4 5 7 8
--------------------------------
Process exited after 0.4954 seconds with return value 0
请按任意键继续. . .