您的位置:首页 > 其它

一生之敌-2017浙江中医药大学程序设计

2017-12-22 09:08 302 查看
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld   


题目描述

大家都知道Alice和Bob两个人是一生之敌。(雾  
但某天,他们两个人发了疯。想知道他们两个是否可以成为朋友。  

于是他们做了一个令人窒息的决定。    

Alice和Bob每个人任意选一个整数。  

假设Alice选择了整数a,Bob选择了整数b。  

Alice使得a做如下变换:  

a -> 2 * a * (a+1)^2

Bob使得b做如下变换:  

b -> b^2

如果变换后的数字相等,则两个人可以化敌为友。  

如果不相等,这两个人怕是石乐志。

现在,你想把Bob部分可能的整数b(存在a变换后的数字等于b变换后的数字)从小到大排列后,知道第一个大于等于n的数字是多少。

输入描述:

第一行输入一个整数T,表示数据组数。
每组数据输入一个整数n。
1 <= T <= 100000
0 <= n <= 10^19
保证结果存在

输出描述:

输出一个整数。


示例1

输入

3
2
6
100


输出

6
6
114


 

这道题当时读了很久,一直搞不懂样例是怎么出来,还是做的题少,没有语感,中文题目都这样了,何况英文题;

读懂题意之后,一看数据范围就知道是二分查找,只需要把a和b做一下变换即可:

b^2 = 2*a*(a+1)^2 -> b = sqrt(2*a)*(a+1);

因为sqrt(2*a)是整数,所以令2*a=4*t*t,所以a=2*t*t;

所以就转换成b=2*t*(2*t*t + 1),所以只需二分

#include <stdio.h>
#include <iostream>
using namespace std;
#define MAX 3e6
typedef unsigned long long ULL;

int main() {
int T;
cin>>T;
while(T--) {
ULL n;
scanf("%llu",&n);
if(n == 0) {
printf("0\n");
continue;
}
ULL l = 0, r = MAX, m, t, ans;
while(l <= r) {
m = l+(r-l)/2;
t = 4*m*m*m + 2*m;
if(t >= n) {
ans = t;
r = m - 1;
}
else {
l = m + 1;
}
}
printf("%llu\n",ans);
}
return 0;
}





                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐