這裏有一個版本,這是平凡O(開方(N)),並避免了所有環路內部分支機構。
先開始生成所有方格直到極限,很容易做到沒有任何乘法,然後初始化l和r指數。
在每次迭代中計算總和,然後根據與目標值的比較更新兩個指標和計數。這是sqrt(N)迭代來生成搜索循環的表和最大sqrt(N)迭代。使用合理的編譯器估計運行時間是每sqrt(N)最多10個時鐘週期,因此對於最大輸入值(如果2^31(sqrt(N)〜= 46341),這應該對應於小於500K時鐘週期或幾十分之一秒第二個的:
unsigned countPairs(unsigned n)
{
unsigned sq = 0, i;
unsigned square[65536];
for (i = 0; sq <= n; i++) {
square[i] = sq;
sq += i+i+1;
}
unsigned l = 0, r = i-1, count = 0;
do {
unsigned sum = square[l] + square[r];
l += sum <= n; // Increment l if the sum is <= N
count += sum == n; // Increment the count if a match
r -= sum >= n; // Decrement r if the sum is >= N
} while (l <= r);
return count;
}
一個好的編譯器可以注意到,這三個末相比都使用相同的操作數,因此只需要一個單一的CMP操作碼,隨後由三個不同的條件移動操作(CMOVcc指令)。
只是注意到,這一輪現在已經結束。 – marcog 2011-01-11 11:10:36
沒有像codejam那樣普及。剛剛纔知道這件事。 – 2011-01-11 11:14:45
@Senthil平臺遇到一些問題可能是件好事。 – marcog 2011-01-11 11:15:37