概括算法——硬幣翻轉問題

   題:有任意N個硬幣正面朝上,每次翻轉n個硬幣知道將N個硬幣所有翻轉成反面。(*表示正面,0表示反面)函數


源代碼以下:code

   

/*
**翻轉硬幣問題,設共有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;
}
是比較簡單的,應該不會有疑問