腾讯面试题:计算抽取的数字

/**-------------------------
* n1和n2满足如下条件:
* 1. n1 + n2 = sum;
* 2. n1*n1 + n2*n2 = sqSum;
* 用角坐标表示n1、n2后可以将
* 条件合并为: sqrt(sqSum)*sin(z) + sqrt(sqSum)*cos(z) = sum
* 化 简 为 :1 + 2*sin(z)*cos(z) = sum*sum/sqSum
* 化 简 为 :sin(2*z) = (sum * sum)/sqSum - 1
* 所以弧度为:z = Math.asin( (sum * sum)/sqSum - 1)/2
* 所以n1 : Math.floor(Math.sin(sqrt(sqSum) * sin(z)))
* 所以n2 : Math.floor(Math.cos(sqrt(sqSum) * sin(z)))
*-------------------------*/

function analyse(){
//模拟抽取
var a = [];
var max = 100000;
var n1 = Math.floor(Math.random() * (max+1));
var n2 = Math.floor(Math.random() * (max+1));
for(var i=1; i<=max; i++){
if( i != n1 && i != n2 ){
a.push(i);
}
}

//计算两数和与平方和
var sum = (max + 1)*(max/2);
var sqSum = max*(max+1)*(2*max+1)/6; //平方和公式: n(n+1)(2n+1)/6
var num;
for(var i=0,len=a.length; i<len; i++){
num = a[i];
sum -= num;
sqSum -= num*num;
}

//计算两数
var z = Math.asin(sum*sum/sqSum - 1)/2;
var r = Math.sqrt(sqSum);
var n3= Math.round(r * Math.sin(z));
var n4= Math.round(r * Math.cos(z));

//返回
return [
[n1, n2].sort().join(','),
[n3, n4].sort().join(',')
]
}

var i, a;
for(i=0; i<1000; i++){
a = analyse();
if(a[0] != a[1]){
console.error(i + '\tnot passed test: ' + a);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值