星际穿越
题目描述
航天飞行器是一项复杂而又精密的仪器,飞行器的损耗主要集中在发射和降落的过程,科学家根据实验数据估计,如果在发射过程中,产生了 x 程度的损耗,那么在降落的过程中就会产生 x2 程度的损耗,如果飞船的总损耗超过了它的耐久度,飞行器就会爆炸坠毁。问一艘耐久度为 h 的飞行器,假设在飞行过程中不产生损耗,那么为了保证其可以安全的到达目的地,只考虑整数解,至多发射过程中可以承受多少程度的损耗?
输入描述:
每个输入包含一个测试用例。每个测试用例包含一行一个整数 h (1 <= h <= 10^18)。
输出描述:
输出一行一个整数表示结果。
示例1
输入
复制
10
输出
复制
2
解题思路
此题为典型的二分查找,由于我们的输入n达到了10^18次方,因此普通的枚举会导致时间超限,由我们计算的表达式为:n>=x*x+x,很容易地证明我们的x值一定在 (0,sqrt(n))的开区间上,所以我们使用二分查找,找到满足条件的最大值即可,复杂度O(log2(n))。
解题代码
import java.util.Scanner;
/**
* 网易-星际穿越
*
* @author yangjieyu
* 解题思路:二分查找,由于我们的输入n达到了10^18次方,因此普通的枚举
* 或导致时间超限,我们计算的表达式为:n>=x*x+x,很容易想到我们的x值一定在 (0,sqrt(n))的开区间上,
* 所以我们使用二分查找,找到满足条件的最大值即可,复杂度log2(n)。
*/
public class Main {
long n;
public static void main(String[] args) {
Main main6 = new Main();
main6.get();
}
private void get() {
Scanner in = new Scanner(System.in);
n= in.nextLong();
long l =0;
long r = (long)Math.sqrt(n);
long resualt = 0;
//二分查找,我们的值一定在 (0,sqrt(n))的开区间上
while(l<=r) {
long mid = (l+r)/2;
if(judge(mid)) {
resualt = mid;
l = mid+1;
}else {
r = mid-1;
}
}
System.out.println(resualt);
in.close();
}
private boolean judge(long mid) {
return n>= mid*mid+mid;
}
}