第6題——最大的奇約數
阿新 • • 發佈:2017-08-09
http spa next 總結 tin 一半 愛好者 system imp
小易是一個數論愛好者,並且對於一個數的奇數約數十分感興趣。一天小易遇到這樣一個問題: 定義函數f(x)為x最大的奇數約數,x為正整數。 例如:f(44) = 11.
現在給出一個N,需要求出 f(1) + f(2) + f(3).......f(N)
例如: N = 7
f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21
小易計算這個問題遇到了困難,需要你來設計一個算法幫助他。
輸入描述:
輸入一個整數N (1 ≤ N ≤ 1000000000)
輸出描述:
輸出一個整數,即為f(1) + f(2) + f(3).......f(N)
輸入例子1:
7
輸出例子1:
21
運行超時的代碼:
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); while(sc.hasNext()){ int N=sc.nextInt(); int sum=0; int i=1; while(i<=N){//奇數的最大約數就是本身,直接求和sum+=i; i=i+2; } int j=2; while(j<=N){//2 6 10 14的最大約數是其一半 sum=sum+j/2; j=j+4; } int k=4; while(k<=N){//其它的數 sum+=evenDivisor(k); k=k+4; } System.out.println(sum); } sc.close(); } //偶數求最大約數的方法*********超時:算法復雜度過大 private static int evenDivisor(int even){ ArrayList<Integer> arr=new ArrayList<Integer>(); for(int i=1;i<=even;i++){ if(even%i==0){ arr.add(i); } } int res=1; for(int i=0;i<arr.size();i++){ if(arr.get(i)%2==1){ res=arr.get(i); } } return res; } }
還是運行超時的:
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); while(sc.hasNext()){ int N=sc.nextInt(); int sum=0; for(int i=1;i<=N;i++){ sum+=maxOdd(i); } System.out.println(sum); } sc.close(); } //偶數求最大約數的方法 private static int maxOdd(int m){ if(m%2==0){ m=m/2; return maxOdd(m); }else{ return m; } } }
所以,不能直接求最大約數,必須找到求和的規律
參考代碼:https://www.nowcoder.com/test/question/done?tid=9685251&qid=46577#summary
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner s=new Scanner(System.in); long num=s.nextInt(); long sum=0; for(long i=num;i>0;i=i/2){ long temp=(i+1)/2; sum+=temp*temp; } System.out.println(sum); } }
總體思路:
因為奇數的最大奇數約數就是自己啊,對於偶數我們只能一直除
2
直到得到一個奇數即為最大奇數約數
比如
1
2
3
4
5
6
7
8
9
10
即n=
10
,此時奇數有
1
3
5
7
9
我們把這幾個奇數相加然後n/
2
得到第二輪序列序列
1
2
3
4
5
分別對應上次的
2
4
6
8
10
五個偶數,這是我們再加
1
3
5
依次類推
細節問題:
當n為偶數,就有n/
2
個奇數,根據等差數列求和公式 即((首項+末項)*項數)/
2
,我們知道n/
2
個奇數和為((
1
+n-
1
)*n/
2
)/
2
,
即為(n/
2
) * (n/
2
),此時n為偶數,因此 (n/
2
) * (n/
2
) = ((n+
1
)/
2
) * ((n+
1
)/
2
)
當n為奇數,有(n+
1
)/
2
個奇數,此時奇數和為((n+
1
)/
2
) * ((n+
1
)/
2
)
因此兩種情況可以用一個等式來總結
第6題——最大的奇約數