一.小結 1.一個boolean變數可以存儲值true或false 2.關係運算符(<,<=,==,!=,>,>=)和數值及字元一起運算 3.布爾運算符&&,|| ,| 和 ^對布爾值和布爾變數進行計算 4.當對p1&&p2求值時,java先求p1的值,如果p1為true,再對p2求值;如果p1為f ...
一、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]