在解決 HDU 1001 這道經典的累加求和問題時,許多初學者會直接套用公式 n*(n+1)/2 來優化時間複雜度,然而卻常因忽略 C 語言的隱性類型轉換規則而導致答案錯誤甚至為零。本文深入剖析這一陷阱的成因,並提供正確的修正方案。
初始代碼如下:
#include <stdio.h>
int main() {
int a;
while(scanf("%d", &a) != EOF)
printf("%d\n\n", a * (1 + a) / 2);
return 0;
}
雖然題目保證最終結果在 32 位有符號整數範圍內,但中間運算 a * (1 + a) 卻可能溢出。當 a 足夠大時(例如 65535),乘積超出 int 範圍,導致溢出後再除以 2 得到的結果為 0 或錯誤值。這正是隱性類型轉換未生效的典型案例:整數運算仍在 int 域內完成,溢出發生在除法之前。
將變量類型提升為 long long(至少 64 位),即可容納中間乘積,避免溢出:
#include <stdio.h>
int main() {
long long a;
while(scanf("%lld", &a) != EOF)
printf("%lld\n\n", a * (1 + a) / 2);
return 0;
}
此時 a 為 long long,根據整數提升規則,1 會被提升為 long long,乘法與除法均在 64 位域內進行,結果正確無誤。
int,則不提升,直接按 int 運算並可能溢出。%lld 對應 long long。掌握類型轉換細節,是寫出健壯 C 程序的關鍵一步。