归纳算法——硬币翻转问题

来源:互联网 发布:java短链接生成原理 编辑:程序博客网 时间:2024/04/29 07:58

   题:有任意N个硬币正面朝上,每次翻转n个硬币知道将N个硬币全部翻转成反面。(*表示正面,0表示反面)


源代码如下:

   

/***翻转硬币问题,设共有N个硬币,一次允许翻转n<N个,需翻转x步,每个硬币翻转y次,**则N*y==n*x,即n/N==y/x,因为要翻转,y必须为奇数,判断n/N若为最简分数,如n不为奇数则不能翻转成功**如果n为奇数,则x取最小值时为n=y,N=x;若n/N不是最简分数,化成最简分数n1/N1,按照上面的步骤**判断,若n1为奇数则可以翻转。*/#include<stdio.h>#include<string.h>char s[100];int gcb(int a,int b);int is_even(int a);int turn_over(int N,int n,int x); int main()  {      int N,n,x,y,g;      int j;      printf("请输入硬币的个数:\n");      scanf("%d",&N);      do      {          printf("请输入一次翻转的硬币个数:\n");          scanf("%d",&n);          g = gcb(N,n);          y = n/g;          if(is_even(y)==0)          printf("不能翻转成功!\n");      }while(is_even(y)==0);      x = N/g;      printf("初始状态:\n");      for(j=0;j<N;j++)      {          s[j]='*';          printf("%3c",'*');      }      printf("\n\n");      turn_over(N,n,x);       return 0;  }int gcb(int a,int b)   //求两个数的最大公约数{    int c;    if(b>a)    {        c = a;        a = b;        b = c;    }    while(b != 0)    {        c = a%b;        a = b;        b = c;    }     return a;}int is_even(int a)  //判断是否为偶数,是则返回0{    while(a > 0)    {        a = a-2;    }     return a;}int turn_over(int N,int n,int x)/*实现翻转函数*/{    int i,j,k;    for(i = 0;i<x;i++)    {      j = N/x*(i);  //第i+1步翻转的起始位置      printf("第%d步:\n",i+1);      getch();      for(k=1;k<=n;k++)  //k计数作用,即每次从s[j]开始翻转n个      {          if(s[j]=='0')            s[j] = '*';          else            s[j] = '0';          j = (j+1)%N;  //j到达上限,但没翻转够n个则从头翻转      }      for(j = 0;j<N;j++)          printf("%3c",s[j]);          printf("\n\n");    }    return 0;}
是比较简单的,应该不会有疑问