Just My Life & My Work

[C++] 3n+1問題 (3n+1 Problem)

今天又談到3n+1,程式很簡單,卻有很大的學問!簡單來說就是一個程式,要求你輸入一個數字,接著程式判斷是否為奇數,若是的話就把這數字「*3+1」,若否的話就「/2」,這是一個迴圈,直到數字n變為1才停止。看以下程式碼:


/**
 Theme: 3n+1 Problem
 Date: 100/04/13
 compiler: Dev C++ 4.9.9.2
 Author: ShengWen
 Blog: https://cg2010studio.wordpress.com/
*/
#include<iostream>
using namespace std;
int main(){
 unsigned long long number;
 cin>>number;
 while(number!=1){
 cout<<number<<endl;
 if(number%2==1)
 number=number*3+1;
 else
 number=number/2;
 }
 cout<<number<<endl;
 system("pause");
 return EXIT_SUCCESS;
}

程式結果(輸入15):

15
15
46
23
70
35
106
53
160
80
40
20
10
5
16
8
4
2
1
請按任意鍵繼續 . . .

很簡單吧!然而它的學問在於:是否存在一個數字n,使得此程式無法回歸到1?目前是沒有答案的!也就是說,若數字可以無限遞增上去,每個數字都要拿來跑一遍,因為數字無窮多,所以就算窮舉也要花很多時間來運算,目前知道2000年04月時,驗證2.88*10^38內都會回歸到1

話說我用C寫了3n+1程式,數字宣告unsigned long long type,無法測試大於18,446,744,073,709,551,615的數字,但有一個Welcome to the 3n + 1 problem!網頁可以玩玩看,可以輸入超級大的數字。

節錄輸入數字1234567899999999的結果

The first term of the sequence is the number itself: 1234567899999999
The next term is: 3703703699999998
The next term is: 1851851849999999
The next term is: 5555555549999998
The next term is: 2777777774999999
The next term is: 8333333324999998
The next term is: 4166666662499999
The next term is: 12499999987499996
The next term is: 6249999993749998

The next term is: 80
The next term is: 40
The next term is: 20
The next term is: 10
The next term is: 5
The next term is: 16
The next term is: 8
The next term is: 4
The next term is: 2
The next term is: 1

收斂速度相當快速,所以不到1秒鐘就可跑出結果:)

之前阿喜老師想要我研究這個問題,讓我想到可以用DP來實做,因為很多數字都會被重複計算,如果過濾掉已經計算過的數字,想必速度會加快不少。

另外,因為C++的無號長整數型態支援範圍[0,18,446,744,073,709,551,615],若想要計算超越此範圍的數字,勢必得動用到大數的加法、乘法、除法,其實後兩者都可以交由大數加法來實現,如「*3」就連「+」自己3次,「/2」則「-」自己的一半。

隨意留個言吧:)~

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料

標籤雲