C語言程序設計100例之(33):加法算式


例33    加法算式

問題描述

看這個加法算式:

☆☆☆ + ☆☆☆ = ☆☆☆

如果每個五角星代表 1 ~ 9 的不同的數字。

這個算式有多少種可能的正確填寫方法?

173 + 286 = 459

295 + 173 = 468

173 + 295 = 468

183 + 492 = 675

以上都是正確的填寫法!

        注意:111 + 222 = 333 是錯誤的填寫法!因為每個數字必須是不同的! 也就是說:1~9中的所有數字,每個必須出現且僅出現一次!不包括數字“0”!

        另外,滿足加法交換率的式子算兩種不同的答案。

輸入格式

        無輸入。

輸出格式

        一個整數,表示可能的算式總數。

        (1)編程思路。

        對1-9進行全排列,然后檢查每種排列是否滿足加法等式要求。

(2)源程序。

#include <stdio.h>

int cnt=0;

void dfs(int a[10],int pos)

{

       if(pos>9)

       {

                  int num1=a[1]*100+a[2]*10+a[3];

                  int num2=a[4]*100+a[5]*10+a[6];

                  int num3=a[7]*100+a[8]*10+a[9];

                  if (num1+num2==num3)

            {

 //             printf("%d + %d = %d\n",num1,num2,num3);

                cnt++;

            }

      }

      else

           for(int i=pos;i<=9;i++)

           {

              int temp = a[i];

              a[i] = a[pos];

              a[pos] = temp;

              dfs(a,pos+1);      // 遞歸

              temp = a[i];

              a[i] = a[pos];

              a[pos] = temp;

        }

}

int main()

{

    int a[10]={0,1,2,3,4,5,6,7,8,9};

    dfs(a,1);

    printf("%d\n",cnt);

    return 0;

}

習題33

33-1  排座位

問題描述

        有3個A國人、3個B國人和3個C國人坐成一排照相。要求任意兩個同一國籍的人不能坐在一起。例如,“A1、B1、A3、B2、C1、B3、C2、A2、C3”就是一種可行的坐法,而“A1、B1、A3、B2、C1、B3、C2、C3、A2”就不滿足要求,因為此時坐在第7和第8兩個位置的人都是C國人。

        求所有位置安排的不同方案總數?

輸入格式

        無輸入。

輸出格式

        一個整數,表示可行的位置安排總數。

     (1)編程思路。

        不妨將9個人分別編號為11、12、13、21、22、23、31、32、33,這樣編號后,編號十位數相同的人一定是同一個國籍。對{11,12,13,21,22,23,31,32,33}這9個數進行全排列,然后判斷每種排列是否符合要求。

    (2)源程序。

#include <stdio.h>

int cnt=0;

int judge(int a[10])  // 判斷同一個國家的兩個人是否挨着

{

    for (int i=1;i<=8;i++)

    {

       if(a[i]/10==a[i+1]/10) return 0;

    }

    return 1;

}

void dfs(int a[10],int pos)

{

    if(pos>9)

       {

           if (judge(a)==1)

        {

              cnt++;

        }

    }

    else

       for(int i=pos;i<=9;i++)

       {

          int temp = a[i];

          a[i] = a[pos];

          a[pos] = temp;

          dfs(a,pos+1);      // 遞歸

          temp = a[i];

          a[i] = a[pos];

          a[pos] = temp;

       }

}

int main()

{

    int a[10]={0,11,12,13,21,22,23,31,32,33};

    dfs(a,1);

    printf("%d\n",cnt);

    return 0;

}

33-2  猜算式

問題描述

        看下面的算式:□□ x □□ = □□ x □□□ 它表示:兩個兩位數相乘等於一個兩位數乘以一個三位數。如果沒有限定條件,這樣的例子很多。

        給出限定是:這9個方塊,表示1~9的9個數字,不包含0。該算式中1至9的每個數字出現且只出現一次!

比如:

46 x 79 = 23 x 158

54 x 69 = 27 x 138

54 x 93 = 27 x 186

        請編程,輸出所有可能的情況! 注意:左邊的兩個乘數交換算同一方案,不要重復輸出!

輸入格式

        無輸入。

輸出格式

        輸出所有滿足要求的乘法等式,每個等式占1行。

輸入樣例

        無輸入

輸出樣例

46*79=23*158

54*69=27*138

54*93=27*186

……  (省略的其他解的情況)

      (1)編程思路1。

        對1-9進行全排列,然后檢查每種一次填入9個方框后是否滿足乘法等式要求。為了不重復輸出,輸出時保證左邊的兩個乘數小數在前,大數在后。

      (2)源程序1。

#include <stdio.h>

void dfs(int a[10],int pos)

{

       if(pos>9)

       {

                  int n1=a[1]*10+a[2];

                  int n2=a[3]*10+a[4];

                  int n3=a[5]*10+a[6];

                  int n4=a[7]*100+a[8]*10+a[9];

                  if (n1<n2 && n1*n2==n3*n4)

                {

                   printf("%d*%d=%d*%d\n",n1,n2,n3,n4);

               }

        }

        else

           for(int i=pos;i<=9;i++)

           {

              int temp = a[i];

              a[i] = a[pos];

              a[pos] = temp;

              dfs(a,pos+1);      // 遞歸

              temp = a[i];

              a[i] = a[pos];

              a[pos] = temp;

        }

}

int main()

{

    int a[10]={0,1,2,3,4,5,6,7,8,9};

    dfs(a,1);

    return 0;

}

      (3)編程思路2。

        設乘法算式中從左到右的四個數分別為a、b、c、d,用三重循環對a、b、c這三個兩位數進行窮舉。其中10≤a≤97,a+1≤b≤98, 10≤c≤98。對窮舉的每種情況,若a和b的積能整除c,則計算出d,然后判斷這4個數中1~9這9個數字是否全部出現。

        為判斷數字1~9是否都出現。定義數組int hash[10],其元素初始值全為0,hash[i]=0表示數字i未出現,數字i出現過,置hash[i]=1。

    (4)源程序2。

#include <stdio.h>

int main()

{

       int a,b,c,d,i;

       int hash[10];

       for (a=10; a<=97; a++)

         for (b=a+1; b<=98; b++)

           for (c=10; c<=98; c++)

        {

            if ((a*b)%c==0)

            {

                d=a*b/c;

                for (i=0;i<10;i++)

                    hash[i]=0;

                hash[a/10]=1; hash[a%10]=1;

                hash[b/10]=1; hash[b%10]=1;

                hash[c/10]=1; hash[c%10]=1;

                hash[d/100]=1; hash[d/10%10]=1; hash[d%10]=1;

                for (i=1;i<=9;i++)

                    if (hash[i]==0) break;

                if (i>9)

                    printf("%d*%d=%d*%d\n",a,b,c,d);

            }

        }

       return 0;

}

33-3  三個3位平方數

問題描述

        將1、2、3、4、5、6、7、8、9九個數字分成三組,每組三個數字構成一個三位數,要求每組中的三位數都組成一個平方數。

        試求出滿足要求的3個三位數。

輸入格式

        無輸入。

輸出格式

        三個從小到大排列的3位整數。

      (1)編程思路1。

        仿照例33的做法,生成1~9的全排列,再判斷全排列的每種情況構成的3個三位數是否都是平方數。

      (2)源程序1。

#include <stdio.h>

#include <math.h>

void dfs(int a[10],int pos)

{

       if(pos>9)

       {

            int num1=a[1]*100+a[2]*10+a[3];

            int num2=a[4]*100+a[5]*10+a[6];

            int num3=a[7]*100+a[8]*10+a[9];

            int i=(int)sqrt(1.0*num1);

            int j=(int)sqrt(1.0*num2);

            int k=(int)sqrt(1.0*num3);

            if (i*i==num1 && j*j==num2 && k*k==num3)

            {

               printf("%d  %d  %d\n",num1,num2,num3);

            }

      }

     else

           for(int i=pos;i<=9;i++)

           {

              int temp = a[i];

              a[i] = a[pos];

              a[pos] = temp;

              dfs(a,pos+1);        // 遞歸

              temp = a[i];

              a[i] = a[pos];

              a[pos] = temp;

        }

}

int main()

{

    int a[10]={0,1,2,3,4,5,6,7,8,9};

    dfs(a,1);

    return 0;

}

      源程序1運行后輸出如下的結果。

361  529  784

361  784  529

529  784  361

529  361  784

784  361  529

784  529  361

        這6個結果按從小到大排列后,本質是一個結果。因此,程序中還需進行去重。

      (3)編程思路2。

        按思路1雖然可以求出3個3位平方數,但並不是這題理想的解法。

        實際上,3位平方數最多有21個(11的平方到31的平方)。因此我們可以先求出所有三位平方數,並且將這些數中出現數字0或存在重復數字的數去掉,例如121、144等。這樣的三位平方數一定少於21個,設有cnt個。再在這cnt個數中任意選取3個數進行組合,看每種組合中的3個3位數的數字是否全部不相同,正好1~9每個數字出現一次。

        為判斷數字1~9是否都出現。定義數組int hash[10],其元素初始值全為0,hash[i]=0表示數字i未出現,數字i出現過,置hash[i]=1。

    (4)源程序2。

#include <stdio.h>

int a[3];

int cnt=0;

void dfs(int p[],int pos,int num)

{

    if (pos==3)

    {

        int hash[10],i;

        for (i=0;i<10;i++)

            hash[i]=0;

        hash[a[0]/100]=1; hash[a[0]/10%10]=1; hash[a[0]%10]=1;

        hash[a[1]/100]=1; hash[a[1]/10%10]=1; hash[a[1]%10]=1;

        hash[a[2]/100]=1; hash[a[2]/10%10]=1; hash[a[2]%10]=1;

        for (i=1;i<=9;i++)

            if (hash[i]==0) break;

        if (i>9)

             printf("%d %d %d\n",a[0],a[1],a[2]);

        return;

    }

    if(3-pos>cnt-num+1) return ;

    for(int i=num;i<cnt;i++)

    {

        a[pos]=p[i];

        dfs(p,pos+1,i+1);

    }

}

int main()

{

    int p[20];

    int i;

    for (i=11;i<=31;i++)

    {

        int a=(i*i)/100;

        int b=(i*i)/10%10;

        int c=(i*i)%10;

        if (a==0 || b==0 ||c==0) continue;

        if (a==b || a==c || b==c) continue;

        p[cnt++]=i*i;

    }

    dfs(p,0,0);

    return 0;

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM