1. 程式人生 > 實用技巧 >[UVA100] The 3n + 1 problem.題解

[UVA100] The 3n + 1 problem.題解

這道橙題也太水了吧!直接模擬輸出流程就可以了!

老規矩,先看題目。

這題讓我們尋找輸入的每對(i,j)[i,j]內所有數字區間長度的max值。我們可以用模擬遞推對[i,j]內所有的數進行相同的操作。
操作流程如下:

想必看了流程圖,思路就更清晰了。但別忘了,我們求的是數n的週期長度即操作次數,所以我們在編寫period函式時要加上計數器count。
以下就是period函式的程式碼了:

1 int period(int x){//period函式對數x進行操作
2     int count=1;//計數器初始化為1,程式至少輸出一次(原始)x
3     while(x!=1){//如果x不為1,繼續對x進行操作
4 if(x%2) x=x*3+1;//x為奇數時,其值為3x+1 5 else x/=2;//否則x為偶數時,其值為x/2 6 count++;//每執行一次操作,操作次數+1 7 } 8 return count;//返回操作次數 9 }

寫好函式程式碼以後,用for迴圈對每對[i,j]區間內的數執行period操作,再用maxn記錄區間內運算元的最大值即可。

那麼以下就是AC程式碼!


程式碼

(註釋版)

 1 #include<bits/stdc++.h>//萬能標頭檔案
 2 using namespace std;
 3 int
i,j; 4 int period(int x){//period函式對數x進行操作 5 int count=1;//計數器初始化為1,程式至少輸出一次(原始)x 6 while(x!=1){//如果x不為1,繼續對x進行操作 7 if(x%2) x=x*3+1;//x為奇數時,其值為3x+1 8 else x/=2;//否則x為偶數時,其值為x/2 9 count++;//每執行一次操作,操作次數+1 10 } 11 return count;//返回操作次數 12 } 13 int main(){//好習慣,程式從主函式讀起 14 while
(cin>>i>>j){//while不斷讀入i,j,直到程式結束 15 int maxn=0;//求最大值要初始化為0 16 for(int a=min(i,j);a<=max(i,j);a++)//a從i,j中較小的開始,遍歷整個區間內所有整數 17 maxn=max(maxn,period(a));//最大值為此次操作次數和之前操作次數中的最大值 18 cout<<i<<" "<<j<<" "<<maxn<<endl;//輸出時別忘了換行endl 19 } 20 return 0;//返回值為0 21 }

(無註釋版)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int i,j;
 4 int period(int x){
 5     int count=1;
 6     while(x!=1){
 7         if(x%2) x=x*3+1;
 8         else x/=2;
 9         count++;
10     }
11     return count;
12 }
13 int main(){
14     while(cin>>i>>j){
15         int maxn=0;
16         for(int a=min(i,j);a<=max(i,j);a++)
17             maxn=max(maxn,period(a));
18         cout<<i<<" "<<j<<" "<<maxn<<endl;
19     }
20     return 0;
21 }

總結

1.while(cin>>i>>j): 讀入每對(i,j)(i,j)直至無可讀取資訊。
2. 在比較最大值和最小值時,記錄最大值、最小值的變數要初始化為最小數和最大數。
3. 碰到一些無思路的操作流程題,建議先模擬遞推尋找思路。