今天做了將近10道project euler上的題,要麼和之前寫的題型類似,要麼簡單,**~
14題雖然簡單些,但是勝在之前沒說過,就一併講一下吧。。。
題意: 在正整數集上定義如下的迭代序列:
n → n/2 (若n為偶數)
n → 3n + 1 (若n為奇數)
從13開始應用上述規則,我們可以生成如下的序列:
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
可以看出這個序列(從13開始到1結束)共有10項。儘管還沒有被證明,但我們普遍認為,從任何數開始最終都能迭代至1(「考拉茲猜想」)。
從小於一百萬的哪個數開始,能夠生成最長的序列呢?
注:序列開始生成後允許其中的項超過一百萬
思路: 如果採用暴力的話,從1到1000000分別列舉,每個數再模擬一下它變成1的過程。時間複雜度估計會大到**吧~
接下來我就想能不能逆推,推出最長的那個數。但是題上說允許迭代的過程中存在大於1000000的數,那麼逆推暫時沒有想到終止條件是什麼。orz~
好吧。。這題我只想到一種思路能在1s內算出來,就是採用記憶化搜尋!由於每個數它的用dp陣列來記錄每個數的迭代步數(初始化dp[1] = 0)。
例如:3的迭代過程是:3->10->5->16->8->4->2->1
此時dp[2] = 1;dp[4] = 2; dp[8] = 3; dp[16] = 4; dp[5] = 5; dp[10] = 6;dp[3] = 7;
我們再看4的迭代時,直接可由dp[4] = 2得到步數為2;
以此類推,看5的迭代時,可由dp[5] = 5得到步數為5;
看6的迭代時,6->3,可由dp[3] + 1得到dp[6] = 7;
這樣就省略了很多很多的中間過程,優化了效率,典型的用空間換取時間。
**如下:
#include #include #include #define ll int64_t
#define d int32_t
#define n 1000000
d dp[n + 5]; //記憶化陣列
d maxx = 0; //記錄最大步數
d dfs (ll n)
if (n <= n && dp[n] != 0)
if (n & 1)
return t;
} else
return t;
}}d main()
}printf("%" prid64"\n", ans);
return 0;
}
最後答案為:837799
如果有寫的不對或者不全面的地方 可通過主頁的****進行指正,謝謝
Project Euler 題目彙總
有乙個面試掛了,然後recruiter讓我多做題並且給我推薦了這個 還挺有趣的,來彙總一下題目 project euler 1.mutiples of 3 and 5 分析可能出現的數字,找規律,利用等差數列 arithmetic progression 求和來解決 project euler 2....
硬幣遊戲 Project Euler 232
原帖 project euler 上最近的題目都還比較意思,來看看前些天剛剛新鮮出爐的一道題 problem232 大意如此 說,有這樣乙個硬幣遊戲,需要兩個玩家參與,我們不防分別將他們稱為玩家 1和玩家 2。遊戲規則如下 兩個玩家輪流來擲硬幣。玩家 1每次只能擲一次,若是正面向上,則得 1分,否則...
014 停止程序
終止程序 入口函式返回 最正確 最正確的方式,只有這樣才能夠保證主線程所有資源都已經被正確的清理 main 函式返回時候 執行緒會被結束 程式內所有的資源都會被釋放 入口函式返回時,為確保以下幾件事情已經完成 主線程所建立的任何物件都已經被正確的銷毀 作業系統會正確的釋放執行緒的堆疊 將程序的推出 ...