狼找兔子问题

一座山周围有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
请按任意键继续. . .

 

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值