1. 程式人生 > >HUD-1001 Sum Problem 解題報告

HUD-1001 Sum Problem 解題報告

題目很簡單

需要注意的是,在輸出中要求每行輸出間有一個空行

如果沒有注意到這點,很容易出現Presentation Error(格式錯誤) 即 PE

題目給出的輸出範圍為32位,所以int就可以解決該問題

解決了這些問題,就可以解題了

比較直接的方法就是暴力迴圈累加:

public class Main {
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()){
			int sum = 0;
			int n = sc.nextInt();
			for(int i = 1;i<=n;i++){
				sum += i;
			}
			System.out.println(sum);
			System.out.println();
		}
	}

}

顯然這並不是這道題的最優解決辦法

在很多時候資料是很龐大的,迴圈並不能很好的解決這類問題

這時可以用到數學中求  等差數列前n項和  的方法

等差數列前n項和公式:

formula

化簡可得:S = (a1 + an) * n / 2  即:(首項 + 尾項)* 項數 / 2 

所以有如下解法:

import java.util.Scanner;

public class Main {
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()){
			int n = sc.nextInt();
			System.out.println((1+n)*n/2);
			System.out.println();
		}
	}

}

但是這種寫法會WA

因為:

System.out.println((1+n)*n/2);

這步計算中 (1+n)* n 可能會超出32位

我們不妨做個驗證,當n=50000時

sum = 1250025000

這是在32位int中的

但計算過程中(1+n)* n = 2500050000 > 2^31-1(int的儲存上限)

超出了int的儲存上限,所以會WA

解決辦法:

WA的原因無非是計算過程中的數超出了int的儲存上限,只要避免超出儲存上限的話,問題就解決了

最簡單的方法就是將運算變為 long 型運算:

import java.util.Scanner;

public class Main {
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()){
			int n = sc.nextInt();
			
			System.out.println((1L+n)*n/2);
			System.out.println();
		}
	}

}

可以看到,在運算中的 1 後面加了一個 L ,這樣可以將 1 轉化成 long 型

int 型與 long 型的值進行運算,運算結果會變成 long 型

這樣的話(1+n)* n 就不會因超出上限而出錯

第二種解決辦法:

如果n是奇數,那麼(n+1)就為偶數,則可將式子轉化為:

(n + 1)/ 2 * n

這樣就不會出現超出上限的情況了,同理,n為偶數:

n / 2 *(n + 1)

程式碼:

import java.util.Scanner;

public class Main {
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()){
			int n = sc.nextInt();
			int sum = (n%2==0)?(n/2*(n+1)):((n+1)/2*n);
			System.out.println(sum);
			
			System.out.println();
		}
	}

}