一、4位數的數字黑洞
任意給定一個4位數(不能所有位都相同),比如:3278,重新組合出最大數:8732,再重新組合出最小數:2378,相減,得到新的4位數(如不足則補0),重復這個程序,最后必然得到一個數字:6174,這個現象被稱為:數字黑洞,
撰寫一個程式,驗證這個現象,
例如,給出四位數3278,則有驗證程序如下:
8732-2378=6354
6543-3456=3087
8730-378=8352
8532-2358=6174
再如,給出四位數1011,則有驗證程序如下:
1110-111=999 (不足4位,補0)
9990-999=8991
9981-1899=8082
8820-288=8532
8532-2358=6174
(1)編程思路,
撰寫函式void parse(int n,int *max,int *min),該函式的功能求出由整數n的四位數字組合成的最大數和最小數,分別通過形參max和min回傳,
在函式中,定義一個陣列int a[4],用于保存整數n的4位數字,然后將陣列a按從小到大的順序排列,之后各數字順序組成最小數,逆序組成最大數,
(2)源程式,
#include <stdio.h> void parse(int n,int *max,int *min) { int a[4],i,j,t; for (i=0; i<4; i++) { a[3-i] = n%10; n/=10; } for (i=0; i<3; i++) // 將四個數字按從小到大順序排列 for (j=0; j<3-i; j++) if (a[j]>a[j+1]) { t = a[j+1]; a[j+1] = a[j]; a[j] = t; } t=0; for (i=0; i<4; i++) t = t * 10 + a[i] ; *min=t; t = 0; for (i=3; i>=0; i--) t= t * 10 + a[i]; *max=t; } int main() { int n,max,min; scanf("%d",&n); do { parse(n,&max,&min); printf("%d-%d=%d\n",max,min,max-min); n=max-min; }while (n!=6174); return 0; }
二、5位數的數字黑洞
任意一個5位數,比如:12345,把它的各位數字打亂,重新排列,可以得到一個最大的數:54321,一個最小的數12345,求這兩個數字的差,得:41976,把這個數字再次重復上述程序(如果不足5位,則前邊補0),如此往復,數字會落入某個回圈圈(稱為數字黑洞),
例如,剛才的數12345會落入:[82962, 75933, 63954, 61974] 這個回圈圈,計算程序如下:
54321 - 12345 = 41976
97641 - 14679 = 82962
98622 - 22689 = 75933
97533 - 33579 = 63954
96543 - 34569 = 61974
97641 - 14679 = 82962
[82962,75933,63954,61974]
再如,整數11211會落入:[74943,62964,71973,83952]這個回圈圈,計算程序如下:
21111 - 11112 = 9999 (不足5位,則前邊補0)
99990 - 9999 = 89991
99981 - 18999 = 80982
98820 - 2889 = 95931
99531 - 13599 = 85932
98532 - 23589 = 74943
97443 - 34479 = 62964
96642 - 24669 = 71973
97731 - 13779 = 83952
98532 - 23589 = 74943
[74943,62964,71973,83952]
還如,整數50000會落入:[53955,59994]這個回圈圈,計算程序如下:
50000 - 5 = 49995
99954 - 45999 = 53955
95553 - 35559 = 59994
99954 - 45999 = 53955
[53955,59994]
撰寫一個程式,找到5位數所有可能的回圈圈,并輸出,每個回圈圈占1行,其中5位數全都相同則回圈圈為 [0],這個可以不考慮,回圈圈的輸出格式仿照:
[82962, 75933, 63954, 61974] 其中數字的先后順序可以不考慮,
(1)編程思路,
如同上面4位數的數字黑洞,撰寫函式int next(int n) ,其功能是求5位整數n的各位數字所組成的最大數與最小數的差值,并將求得的差值作為函式值回傳,
為了找出一個整數n的回圈圈,撰寫一個函式void heidong(int n),尋找整數n的回圈圈,在函式中,定義一個陣列int a[20]用于保存計算程序中的每一個差值,
初始時,置a[0]=n,之后用next()函式求得n的各位數字組成的最大數與最小數的差值,保存到a[1]中,即a[1]=next(a[0]),再求 a[2]=next(a[1]),…,a[i]=next(a[i-1]),
每次求得了a[i]后,將a[i]與a[0]~a[i-1]中保存的各數依次比較,若每個a[j]==a[i](0≤j≤i-1),則找到了回圈圈 a[j]~a[i-1],輸出這個回圈圈,并將這個回圈圈中的各個數保存到全域陣列b中,
之所以要將回圈圈中的數保存到全域陣列中,是因為很多5位數會落在同一個回圈圈中,例如,整數10000會落在[74943,62964,71973,83952]回圈圈中,11112、11121、11211、…這些數同樣落在這個回圈圈中,這樣當計算10000找到了回圈圈后,將74943、62964、71973、83952這4個數保存在全域陣列b中,當以后計算到11112時,找到了回圈圈,由于回圈圈中的數74943已在全域陣列b中存在,因此這個回圈圈是重復的,無需輸出,這樣,可以用回圈
for(i=10000;i<99999;i++)
{
if (next(i)==0) continue; // 各位數字全部相同,忽略
heidong(i);
}
找出所有5位數可能的回圈圈,
(2)源程式,
#include<stdio.h> int b[12]={0}, cnt=0; // 保存各回圈圈中的數避免重復,cnt為黑洞中數的個數 int next(int n) // 整數n各位數字組成的最大數與最小數的差 { int a[5],i,j; for (i=0;i<5;i++) { a[i]=n%10; n/=10; } for (i=0;i<4;i++) for (j=0;j<4-i;j++) if (a[j]>a[j+1]) { int t; t=a[j]; a[j]=a[j+1]; a[j+1]=t; } int max=0,min=0; for (i=0;i<5;i++) { min=min*10+a[i]; max=max*10+a[4-i]; } return max-min; } void heidong(int n) { int a[20],flag=0; a[0]=n; int i,j,k; for (i=1; ;i++) { a[i]=next(a[i-1]); for (j=0;j<i;j++) { if(a[i]==a[j]) // a[j]~a[i-1]之間的數構成回圈圈 { for (k=0;k<cnt;k++) // 看當前回圈圈中的數是否保存過,本質是查重 { if(a[i]==b[k]) { flag=1; break;} } if (flag!=1) // 輸出回圈圈中的各數,同時保存到全域陣列b中 { printf("[%d",a[j]); b[cnt++]=a[j]; for (k=j+1;k<i;k++) { printf(",%d",a[k]); b[cnt++]=a[k]; } printf("]\n"); flag=1; } } } if (flag==1) break; } } int main() { int i; for(i=10000;i<99999;i++) { if (next(i)==0) continue; // 各位數字全部相同,忽略 heidong(i); } return 0; }
運行程式可知,所有5位數可能的回圈圈有3個,如下,
[74943,62964,71973,83952]
[63954,61974,82962,75933]
[53955,59994]
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/537980.html
標籤:C
