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

例15   除法算式

問題描述c++

輸入正整數n(2≤n≤68),按從小到大輸出全部形如abcde/fghi=n的表達式。其中a~i爲1~9的一個排列。算法

輸入格式編程

每行爲一個正整數n (n <= 1500),輸入n=0結束。數組

輸出格式測試

輸出知足條件的全部形如abcde/fghi=n的表達式,每一個表達式佔一行,具體格式參見輸出樣例。優化

輸入樣例spa

43d

20io

62搜索

0

輸出樣例

15768/3942=4

17568/4392=4

23184/5796=4

31824/7956=4

No Solution!

79546/1283=62

94736/1528=62

(1)編程思路。

本例須要先肯定好窮舉的思路。雖然題目說a~i爲1~9的一個排列,但窮舉1~9的全部排列顯然沒有必要。

能夠窮舉除數fghi,這是一個4位數,最小可爲1234,最大可爲9876,而後按fghi*n計算出abcde,最後判斷這9個數字是否不相同。

爲判斷9個數字是否相同,能夠定義一個數組flag[10],其中flag[i]的值表示數字i在算式中出現的次數,顯然flag[1]~flag[9]的值全爲1才知足要求。

另外,在窮舉時進行適當優化。若計算出abcde小於12345,顯然除數fghi過小,直接增大除數進行下次窮舉;若計算出abcde大於98765,顯然除數fghi太大,再也不可能找到解,直接退出窮舉循環。

(2)源程序。

#include <stdio.h>

int main()

{

    int n,x,y,i,flag[10],t;

    while (scanf("%d",&n) && n!=0)

    {

        t=0;

        for (y=1234;y<=9876;y++)

        {

            x=y*n;

            if (x<12345) continue;

            if (x>98765) break;

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

               flag[i]=0;

            flag[x/10000]++; flag[x%10000/1000]++;

            flag[x%1000/100]++; flag[x%100/10]++;

            flag[x%10]++;

            flag[y/1000]++; flag[y%1000/100]++;

            flag[y%100/10]++; flag[y%10]++;

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

                if (flag[i]!=1) break;

            if (i==10)

            {

                printf("%d/%d=%d\n",x,y,n);

                t++;

            }

        }

        if (t==0) printf("No Solution!\n");

    }

    return 0;

}

習題15

15-1  完美立方

問題描述

a3 +b3 + c3 = d3爲完美立方等式。例如13 + 63 + 83 =93。編寫一個程序,輸出100之內的全部四元組(a, b, c, d),使得a3 +b3 + c3 = d3,其中1≤a< b< c< d≤100。

輸入格式

無輸入

輸出格式

100之內全部知足a3 +b3 + c3 = d3的四元組(a, b, c, d),每行輸出5組。

輸入樣例

無輸入

輸出樣例

(  3,  4,  5,  6)  ( 1, 6,  8,  9)  ( 6,  8, 10, 12)  (  2, 12, 16, 18)  (  9, 12, 15, 18)

(  3,  10, 18, 19)  ( 7, 14, 17, 20)  ( 12, 16, 20, 24)  (  4, 17, 22, 25)  (  3, 18, 24, 27)

……

(1)編程思路。

由於要求100之內全部知足a3 +b3 + c3 = d3的四元組(a, b, c, d),所以先定義一個數組int cube[101];,且cube[i]的值賦i3,以便於後面直接引用。

從d出發進行窮舉,則窮舉範圍爲

6≤d≤100

1≤a≤d-3

a+1≤b≤d-2

b+1≤c≤d-1

(2)源程序。

#include <stdio.h>

int main()

{

    int  i, a, b, c, d,cnt=0;

    int cube[101];

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

       cube[i]=i*i*i;

    for (d=6 ; d<=100; d++)

       for (a=1; a<d-2; a++ )

       {

          if (cube[d] <cube[a]+cube[a+1]+cube[a+2]) break;  // 不必繼續搜索b 和c

          for (b=a+1 ; b<d-1; b++)

          {

              if (cube[d] <cube[a]+cube[b]+cube[b+1])  break; //  不必繼續搜索c

              for (c=b+1; c<d;  c++)

                 if (cube[d]==cube[a]+cube[b]+cube[c])

                  {

                                cnt++;

                                printf("(%3d,%3d,%3d,%3d)  ",a,b,c,d);

                                if (cnt%5==0) printf("\n");

                  }

         }

    }

    return 0;

}

15-2  分數拆分

問題描述

輸入正整數k,找到全部的正整數x≥y,使得1/k=1/x+1/y。

輸入格式

輸入包含多組測試數據,每組爲一行,一個正整數k。

輸出格式

對每組數據先輸出解的個數,而後輸出所有的解,沒個解佔一行。具體格式參見輸出樣例。

輸入樣例

2

12

輸出樣例

2

1/2=1/6+1/3

1/2=1/4+1/4

8

1/12=1/156+1/13

1/12=1/84+1/14

1/12=1/60+1/15

1/12=1/48+1/16

1/12=1/36+1/18

1/12=1/30+1/20

1/12=1/28+1/21

1/12=1/24+1/24

(1)編程思路。

乍一看窮舉的範圍好像沒法肯定,但因爲x≥y, 有1/x≤1/y,

所以由1/k=1/x+1/y 可知  1/y =1/k-1/x≥1/k-1/y, 故 2/y≥1/k  即y≤2k。固然y≥k+1。這樣只要在k+1~2k範圍以內窮舉y,而後根據y嘗試計算出x便可。

(2)源程序1。

#include <stdio.h>

int main()

{

    int k;

    while (scanf("%d",&k)!=EOF)

    {

        int x,y,cnt=0;

        for (y=k+1;y<=2*k;y++)

        {

            if(k*y%(y-k)==0)

            {

                cnt++;

            }

        }

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

        for (y=k+1;y<=2*k;y++)

        {

            if(k*y%(y-k)==0)

            {

                x=k*y/(y-k);

                printf("1/%d=1/%d+1/%d\n",k,x,y);

            }

        }

    }

    return 0;

}

       (3)源程序2。

        在源程序1中,窮舉的循環進行了兩次,一次用循環求出解的個數,另外一次用循環輸出各個解的狀況。顯然,能夠在用循環求解的個數時用數組將求得的解的狀況保存下來,這樣就不用再次循環求解,直接輸出用數組保存的解的狀況便可。

#include <stdio.h>

int main()

{

    int k;

    while (scanf("%d",&k)!=EOF)

    {

        int cnt=0;

        int t;

        int x[2*k],y[2*k];

        for (t=k+1;t<=2*k;t++)

        {

            if(k*t%(t-k)==0)

            {

                x[cnt]=k*t/(t-k);

                y[cnt]=t;

                cnt++;

            }

        }

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

        for (t=0;t<cnt;t++)

        {

            printf("1/%d=1/%d+1/%d\n",k,x[t],y[t]);

        }

    }

    return 0;

}

        注意:在上面的源程序2中,x和y數組是定義的可變長數組,如今的C標準支持這樣的用法。

15-3  一數三平方

問題描述

有一類六位數,不只它自己是平方數,並且它的前三位與後三位也都是平方數,這類數稱爲「一數三平方數」。

輸入格式

無輸入

輸出格式

輸出全部的一數三平方數。每行輸出一個一數三平方數,具體格式參見輸出樣例。

輸入樣例

無輸入

輸出樣例

144400 : 12*12=144,20*20=400,380*380=144400

225625 : 15*15=225,25*25=625,475*475=225625

……

  (1)編程思路。

若是程序對全部的六位數(100000~999999)進行窮舉,判斷這個六位數是不是一數三平方,顯然比較麻煩。

因爲一個「一數三平方」數,其前三位與後三位必定都是平方數,所以,能夠先求出999之內的全部的平方數,最多隻有32個(即0的平方~31的平方,32的平方1024超過了3位)。定義一個數組int a[32]來保存這32個平方數。

程序中對這32個平方數兩兩組成的六位數進行窮舉判斷,顯然高三位必須爲數組中a[10](即不小於10的平方100的數首位纔不爲0)以後的平方數。算法描述爲:

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

                   for(j=0;j<=31;j++)

                   {

                            c=1000*a[i] +a[j];              // a[i]做爲高三位、a[j]做爲低三位構成六位數

                            if( c是平方數)

                                 輸出相應信息並計數

                   }

       (2)源程序。

#include <stdio.h>

#include <math.h>

int main()

{

         int a[32],i,j;

         long b,c,t;

         for(i=0;i<=31;i++)              // 統計出從0到999以內的全部平方數

                   a[i]=i*i;

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

         {

                   b=1000*a[i];                                /*高三位數*/

                   for(j=0;j<=31;j++)

                   {

                            c=b+a[j];                              /*六位數*/

                            t=sqrt(c);                             /*六位數開方*/

                            if(c==t*t)                             /*判斷六位數是否爲平方數*/

                            {

                                     printf("%d : %d*%d=%d,%d*%d=%d,%d*%d=%d\n",c,i,i,a[i],j,j,a[j],t,t,c);

                            }

                   }

         }

    return 0;

}

相關文章
相關標籤/搜索