蓝桥杯 每周一练 第一周(3n+1问题)
[問題描述]
?
考慮如下的序列生成算法:從整數(shù) n 開始,如果 n 是偶數(shù),把它除以 2;如果 n 是奇數(shù),把它乘 3 加1。
用新得到的值重復上述步驟,直到 n = 1 時停止。例如,n = 22 時該算法生成的序列是:
22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
?
人們猜想(沒有得到證明)對于任意整數(shù) n,該算法總能終止于 n = 1。這個猜想對于至少 1 000 000內(nèi)的整數(shù)都是正確的。
?
對于給定的 n,該序列的元素(包括 1)個數(shù)被稱為 n 的循環(huán)節(jié)長度。在上述例子中,22 的循環(huán)節(jié)長度為 16。
輸入兩個數(shù) i 和 j,你的任務(wù)是計算 i 到 j(包含 i 和 j)之間的整數(shù)中,循環(huán)節(jié)長度的最大值。
?
[輸入]
輸入每行包含兩個整數(shù) i 和 j。所有整數(shù)大于 0,小于 1 000 000。
?
[輸出]
對于每對整數(shù) i 和 j,按原來的順序輸出 i 和 j,然后輸出二者之間的整數(shù)中的最大循環(huán)節(jié)長度。這三個整數(shù)應(yīng)該用單個空格隔開,且在同一行輸出。對于讀入的每一組數(shù)據(jù),在輸出中應(yīng)位于單獨的一行。
?
[樣例輸入]
1 10
100 200
201 210
900 1000
?
[樣例輸出]
1 10 20
100 200 125
201 210 89
900 1000 174
?
思路分析
將i和j從小到大遍歷一遍,遍歷的過程中求出每個數(shù)經(jīng)過題目中的規(guī)則得到1時停止,保留所需的循環(huán)節(jié)長度,與這個數(shù)之前的最大循環(huán)節(jié)長度進行比較,取大數(shù),即可。
坑1:i和j不一定是i>j,要判斷一下
坑2:中間重復的步驟太多,要按照上訴步驟直接求出,會超時,所以需要用HashMap 存一下前面的數(shù)(key)對應(yīng)的循環(huán)節(jié)長度(value),后面再求的時候,先查詢一下該數(shù)(key)是否存在,若存在,可直接取出來用,若不存在,再進行計算,這樣會省去對一個數(shù)的重復計算。
?
java 代碼如下:
import java.util.Scanner; import java.util.HashMap; public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int i,j,MaxCount=-1;HashMap<Integer,Integer> map = new HashMap();Integer count = 1;int a,b;//循環(huán)接收數(shù)據(jù)while(sc.hasNext()){i = sc.nextInt();j = sc.nextInt();a = i;b = j;//判斷兩數(shù)的大小if (a > b) {a = j;b = i;}//循環(huán)求出i和j之間的數(shù)換算到1的循環(huán)節(jié)長度,求最大循環(huán)節(jié)長度for (int k = a ; k <= b; k++) {count = map.get(k);if(count==null){count = f(k);map.put(k, count);}MaxCount = Math.max(count, MaxCount);}System.out.println(i+" "+j+" "+MaxCount);MaxCount = -1;}}//計算循環(huán)節(jié)長度static int f(long k) {int count = 1;while (k != 1) {if ((k & 1) == 0) {k /= 2;} else {k = k * 3 + 1;}count++;}return count;} }?
轉(zhuǎn)載于:https://www.cnblogs.com/l199616j/p/10578057.html
總結(jié)
以上是生活随笔為你收集整理的蓝桥杯 每周一练 第一周(3n+1问题)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++Primer第五版——习题答案详解
- 下一篇: EF创建上下文对象HttpContext