C語言程序設計100例之(8):尼科徹斯定理

例8    尼科徹斯定理

題目描述編程

尼科徹斯定理能夠敘述爲:任何一個整數的立方均可以表示成一串連續的奇數的和。須要注意的是,這些奇數必定是連續的,如:1,3,5,7,9,…。數組

例如,對於整數5,5*5*5=125=21+23+25+27+29。函數

對於整數6,216=31+33+35+37+39+41,spa

也能夠表示爲216=7+9+11+13+15+17+19+21+23+25+27+29。排序

請你編寫程序對這個定理進行驗證。數學

輸入格式io

一個整數n(2≤n≤1000)。變量

輸出格式循環

將n的立方表示爲一串連續的奇數的和,具體格式見輸出樣例。如有多種表示方式,任意輸出一種便可。程序

輸入樣例

29

輸出樣例

29*29*29=24389=813+815+817+819+821+823+825+827+829+831+833+835+837+839+841+843+845+847+849+851+853+855+857+859+861+863+865+867+869

        (1)編程思路1。

        先計算輸入數n的立方num,而後從1(用變量i記錄)開始累計和sum,累計每次j加2保證下個數也爲奇數,若是累加和sum大於立方數num時,跳出本次循環,進行下一次的嘗試(i=3或五、七、…開始累積和)。當找到後,記錄開始位置(即i),結束位置(即j),輸出。

        程序寫成一個嵌套的二重循環。外循環i控制累計和的起點,內循環累計i、i+二、i+四、…的和。

      (2)源程序1。

#include<stdio.h>

int main()

{

    int n,num,sum,i,j,k,flag;

    while(1)

    {

         scanf("%d",&n);

         if(n==0)  break;

         num = n * n * n;

         flag=0;

         for(i=1; i<num && flag==0; i=i+2)

        {

            sum=0;

            for(j=i; j<num; j=j+2)

            {

               sum += j;

               if(sum == num)

              {

                  printf("%d*%d*%d=%d=%d",n,n,n,num,i);

                  for (k=i+2; k<=j;k+=2)

                      printf("+%d",k);

                  printf("\n");

                  flag=1;

                  break;

              }

              else if (sum > num)

                  break;

           }

       }

    }

    return 0;

}

      (3)編程思路2。

        源程序1的思路是經過試探的方法來驗證尼科徹斯定理,採用二重循環實現。

        實際上,n的立方必定能夠表示爲一個等差數列的各項和,該等差數列的首項爲n*n-n+1,公差爲2,項數爲n。

        按等差數列的求和公式知該數列的和爲:

        [(n*n-n+1)+( n*n-n+1)+ 2 (n-1)]*n/2 =n*n*n

        所以,直接用循環輸出這個等差數列的各項便可。

       (4)源程序2。

#include<stdio.h>

int main()

{

    int n,a,i;

    while(1)

    {

         scanf("%d",&n);

         if(n==0)  break;

        // 輸出等差數列,首項爲n*n-n+1,公差爲2,項數爲n

        a=n*n-n+1;

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

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

             printf("+%d",a+i*2);

        printf("\n");

    }

    return 0;

習題8

8-1  谷角猜測

題目描述

日本數學家谷角靜夫在研究天然數時發現了一個奇怪現象:對於任意一個天然數 n ,若 n 爲偶數,則將其除以 2 ;若 n 爲奇數,則將其乘以 3 ,而後再加 1 。如此通過有限次運算後,總能夠獲得天然數 1 。人們把谷角靜夫的這一發現叫作「谷角猜測」。

請你編寫程序對這個猜測進行驗證。

輸入格式

一個天然數n。

輸出格式

把 n 通過有限次運算後,最終變成天然數 1 的全過程輸出。具體格式見輸出樣例。

輸入樣例

34

輸出樣例

34/2=17

17*3+1=52

52/2=26

26/2=13

13*3+1=40

40/2=20

20/2=10

10/2=5

5*3+1=16

16/2=8

8/2=4

4/2=2

2/2=1

         (1)編程思路。

        定義迭代變量爲n,按照谷角猜測的內容,能夠獲得兩種狀況下的迭代關係式:當 n 爲偶數時,n=n/2 ;當 n 爲奇數時, n=n*3+1 。

        這就是須要計算機重複執行的迭代過程。這個迭代過程須要重複執行多少次,才能使迭代變量 n 最終變成天然數 1 ,這是咱們沒法計算出來的。所以,還需進一步肯定用來結束迭代過程的條件。因爲對任意給定的一個天然數 n ,只要通過有限次運算後,可以獲得天然數 1 ,從而完成驗證工做。所以,用來結束迭代過程的條件能夠定義爲: n==1 。

       (2)源程序。

#include<stdio.h>

int main()

{

   unsigned int data;

   scanf("%d",&data);

   while(data!=1)

   {

        if((data%2==0))

        {

                 printf("%d/2=%d\n",data,data/2);

                 data/=2;

         }

        else

        {

                printf("%d*3+1=%d\n",data,data*3+1);

                data=data*3+1;

        }

   }

   return 0;

}

8-2  四方定理

題目描述

數論中著名的「四方定理」是:全部天然數至多隻要用四個不小於0的整數的平方和就能夠表示。

編寫一個程序驗證此定理。

輸入格式

一個天然數n。

輸出格式

把天然數 n 表示爲四個數的平方和。具體格式見輸出樣例。

輸入樣例

147

輸出樣例

7*7+7*7+7*7+0*0=147

8*8+7*7+5*5+3*3=147

9*9+5*5+5*5+4*4=147

9*9+7*7+4*4+1*1=147

9*9+8*8+1*1+1*1=147

11*11+4*4+3*3+1*1=147

11*11+5*5+1*1+0*0=147

12*12+1*1+1*1+1*1=147

        (1)編程思路。

        對於待驗證的天然數n,用四個變量i、j、k、l採用試探的方法,窮舉進行計算,知足要求(i *i + j * j + k * k + l * l == n)時輸出計算結果。

        在窮舉時,不妨設i≥j≥k≥l。所以,窮舉的範圍可肯定爲:

1 ≤ i ≤ n/2

0 ≤ j ≤ i

0 ≤ k ≤ j

0 ≤ l ≤ k

       (2)源程序。

#include<stdio.h>

int main()

{

    int n,i,j,k,l;

    scanf("%d",&n);

    for (i = 1; i <= n/2; i++)          // 對i,j,k,l進行窮舉

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

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

                for (l = 0; l <= k; l++)

                    if (i *i + j * j + k * k + l * l == n)

                     {

                          printf("%d*%d+%d*%d+%d*%d+%d*%d=%d\n",i,i,j,j,k,k,l,l,n);

                      } 

   return 0;

}

8-3  卡布列克運算

問題描述

所謂卡布列克運算,是指任意一個四位數,只要它們各個位上的數字不全相同,就有這樣的規律:

(1)把組成這個四位數的四個數字由大到小排列,造成由這四個數字構成的最大的四位數;

(2)把組成這個四位數的四個數字由小到大排列,造成由這四個數字構成的最小的四位數(若是四個數字中含有0,則此數不足四位);

(3)求出以上兩數之差,獲得一個新的四位數。

重複以上過程,總能獲得最後的結果是 6174。

例如,n= 3280,驗證結果爲:8320-238=8082  8820-288=8532  8532-2358=6174

編寫一個程序對卡布列克運算進行驗證。

輸入數據

一個各位上的數字不全相同的四位數n。

輸出要求

把 n 通過有限次卡布列克運算後,最終變成6174的全過程輸出。具體格式見輸出樣例。

輸入樣例

2019

輸出樣例

9210-129=9081

9810-189=9621

9621-1269=8352

8532-2358=6174

 YES

       (1)編程思路。

爲實現驗證程序,編寫4個函數。

void parse_sort(int each[],int num) 將num分解爲各位數字並排序後存入數組each[]中。

int minD(int each[]) 求數組each中的4個數字可組成的最大數。

int maxD(int each[]) 求數組each中的4個數字可組成的最小數。

int pow10_int(int n) 求10的N次方。

     (2)源程序。

#include <stdio.h>

#define N 4

int pow10_int(int n);  // 求10的N次方

void parse_sort(int each[],int num); // 把num分解各個位上的數後存入數組each[]中

int minD(int each[]);  // 求數組each可組成的最大數

int maxD(int each[]);  // 求數組each可組成的最小數

int main()

{

    int number,max,min;

    int each[N];

    scanf("%d",&number);

    while(number!=6174)

    {

        parse_sort(each,number);

        max=maxD(each);

                   min=minD(each);

                   number=max-min;

                   printf("%d-%d=%d\n",max,min,number);

    }

    printf(" YES\n");

    return 0;

}

int pow10_int(int n)  // 求10的N次方的函數

{

    int sum=1;

    for(int i=0;i<n;i++)

         sum=sum*10;

    return sum;

}

void parse_sort(int each[],int num) // 把num分解各個位上的數後存入數組each[]中

{

         int m,i,j,t;

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

                    each[i]=0;

          i=0;

         while(num!=0)

          {

               m=num%10;   num=num/10;

              each[i++]=m;

         }

         for(i=0;i<N-1;i++)

             for (j=0;j<N-1-i;j++)

                     if (each[j]>each[j+1])

                     {

                              t=each[j];

                              each[j]=each[j+1];

                              each[j+1]=t;

                     }

}

int minD(int each[])  // 求數組each可組成的最大數

{

    int sum=0,i;

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

        sum+=each[i]*pow10_int( (N-1-i) );

    return sum;

}

int maxD(int each[])  // 求數組each可組成的最小數

{

    int sum=0,i;

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

        sum=sum+each[i]*pow10_int(i);

    return sum;

相關文章
相關標籤/搜索