从0到N(50000)的N个数字,抽掉其中两个数

 

题目:一个组数据从0到N(50000)的N个数字依次递增且不重复,现抽掉其中两个数,并把剩下的49998个数字打乱装入int A[]数组中。请在只遍历一次循环且最多只可用到5个变量,找出这2个抽出的数字。

 

简单答案:

 

 

long a=0,b=0;

for(int i=1;i<=50000;i++)
{
 a += i;
 b += (i*i);

 if(i<49998)
 {
  a -= A[i-1];
  b -= (A[i-1]*A[i-1]);
 }
}
/*
到此,假设未知数是,x1,x2;上面也是主要算出a,b 的值
即x1+x2 = a;
x1*x1 + x2*x2 = b;
那么可通过数学的求未知数可行:x1*x2 = (a*a-b)/2;
*/

cout<<"x1= " << (sqrt(2*b-a*a)+a)/2 << ", x2="<< (a -(sqrt(2*b-a*a)+a)/2)<<endl;

 

感谢仁兄:

Qiongzhu


思路:

遍历一次数组,求出这两个数的和a+b 与平方和a*a+b*b
a+b = 1+2+3+4+...+N- sum(A[]); (1)
a*a+b*b = (1*1)+(2*2)+(3*3)+(4*4)+...+(N*N) / sum(A[]*A[]); (2)

假设
m=a+b
n=a*a+b*b

a=(m+sqrt((2*n-m*m)))/2
b=(m-sqrt((2*n-m*m)))/2

边界
N < pow(2, 17)
N*N < pow(2, 34) < pow(2, 63)
1+2+3+4+...+N的值为N*(N+1)/2 < pow(2, 33) < pow(2, 63)
(1*1)+(2*2)+(3*3)+(4*4)+...+(N*N) < N*N*N < pow(2, 50) < pow(2, 63)
使用编译器的扩展长整型__int64,可以表示和,以及平方和

 

来自

别想太复杂,只要以数学的解法可解


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值