袋子A中有1000个球,每个球按从1到1000进行编号,现从袋子A中随意取出两个球扔掉,现在,我们每次从袋子A中随意取出一个球,确认其编号后放入袋子B,直到袋子A变空。请找出扔掉的两个球的编号。要求:使用C++实现,最多只能定义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的值来.