1. 程式人生 > >【HDU 1032】The 3n + 1 problem

【HDU 1032】The 3n + 1 problem

思路

  • 思路比較簡單,遞迴加儲存

    • 網上有人說,不用儲存也能過(沒有試)
    • 但是需要注意n的範圍,否則陣列會越界
    • 因為3*n+1的結果可能比3000000還要大(最開始一直沒有想通)
    • 所以超出1000000的數,就不儲存
  • 輸入的i j不一定是從小到大

程式碼

#include <iostream>
using namespace std;

//儲存n對應的迴圈長度 
int tab[1000000+10];

//返回n對應的迴圈長度 
int f(int n){
	if(n == 1)						//當n為 1,遞迴出口 
		return 1;					//迴圈長度為 1 
	int tmp;						//計算出的臨時變數 
if(n > 1000000 || tab[n] == 0){ //超出表的範圍或還沒有計算 if(n % 2 == 1){ //奇數 tmp = f(3*n + 1) + 1; //迴圈長度加 1 }else{ //偶數 tmp = f(n / 2) + 1; //迴圈長度也加 1 } if(n <= 1000000){ //在表的範圍內 tab[n] = tmp; //記錄在表中 } return tmp; //返回迴圈長度 } return tab[n]; //已經在表中時,直接返回 } int main(){ int i,
j, t1, t2; // while(cin >> t1 >> t2){ //t1 t2儲存輸入順序 if(t1 > t2){ //交換t1 t2的位置 i = t2; //讓 i 小於 j j = t1; }else{ i = t1; j = t2; } int max = f(j); //max先賦值為其中的一個值 for(int k = i; k < j; k++){ //迴圈整個範圍(j已經賦值給max) if(f(k) > max){ max = f(k)
; //記錄最大值 } } cout << t1 << " " << t2 << " " << max << endl; } return 0; }

總結

  • 讀題目不太認真,沒有看到輸出的順序跟輸入要一致
  • 預設i j從小到大
  • 使用陣列時,沒有考慮到訪問越界的情況