從1到N(100000)中任意拿掉兩個數,把剩下的99998個數順序打亂,并且放入數組A中。要求只掃描一遍數組,把這兩個數找出來??梢允褂米畹讲怀^5個局部變量,不能用數組變量,并且不能改變原數組的值。
思路:
遍歷一次數組,求出這兩個數的和a+b 與積a*b
a+b = 1+2+3+4+...+N- sum(A[]);??? (1)
a*b =? 1*2*3*4*...*N / multi(A[]);?? (2)
主要解決sum與multi的溢出問題
(1) 可化為 (N-A[0]) + (N-1-A[1]) + ...+ (3-A[N-3]) + 2 + 1
(2) 可以用對數來代替原數進行求積的等價運算,避免溢出的問題,但是這種方法會產生一些精度上的問題,不知道大家有什么更好的方法!
先求出log(a*b)?:
?????????????????????????= log(1*2*3*4*....*N)/log(A[0]*A[1]*A[2]*...*A[N-3])
?????????????????????????= log(N)-log(A[0]) + log(N-1)-log(A[1]) + ... +log(3)-log(A[N-3]) + log(2) + log(1)
?????????
知道了兩數的和與積,由此就可以計算出a跟b的值來.
代碼如下:






























































PS(謝謝枝~的幫助)請大家指導
//................................
通過大家的幫助:
得到另一個寫法,不會產生精度問題
(1+N)*N /2 - S = a + b
1/6 * n*(n + 1)*(2n + 1) - X = a*a + b*b
注:
1/6 * n*(n + 1)*(2n + 1)=1*1 + 2*2 + 3*3 +...+N*N
X = A[0]*A[0] + A[1]*A[1] +...A[N-3]*A[N-3]
?
==>
a + b = m
a*a + b*b = n
由于可解出a,b
????unsigned?int?sum?=?0;
????unsigned?int?sqrSum?=?0;
????for(i=0;?i<N-2;?i++)
????{
????????sum?+=?N-i-A[i];???????
????????sqrSum?+=?((N-i)*(N-i))?-?((A[i])*A[i]);
?????
????}
????sum?+=?2?+?1;?
????sqrSum?+=?2*2?+?1*1;
????unsigned?int?sqrSum?=?0;
????for(i=0;?i<N-2;?i++)
????{
????????sum?+=?N-i-A[i];???????
????????sqrSum?+=?((N-i)*(N-i))?-?((A[i])*A[i]);
?????
????}
????sum?+=?2?+?1;?
????sqrSum?+=?2*2?+?1*1;