解析: 题目不难,但是有点绕口,一开始看了好多遍都读不懂,而且还有个地方有坑。
先说下什么是完全平方数,完全平方数是指一个数开根方后是一个整数,比如3*3=9,这个9就是完全平方数。
另外题目的最后说明了n是有符号的整数,也就是说因为符号位占了一个位,一个数据类型下的最大数会比无符号的小很多,比如int类型的本来是有8位二进制组成,现在就只有7位组成了。这里是个天坑啊,一开始没注意数据范围,一直拿不到满分。
实现方式有两种
- 可以直接调用java里面自带的Math.sqr()方法对一个数开平方根,如果开平方根的数是一个整数,那么就说明这个数是完全平方数。这种方法很方便,步骤都交给了系统去实现,但是因为Math.sqr()方法是每个数逐个比较的,知道得出平方根数,这样比较耗时。
- 另一种方法是自己手写一个二分法去实现,这样程序的比较次数就少了一半,时间也快一倍
方法一:Math.sqr()
package _3_5_test;
import java.util.Scanner;
/*大等于n的最小完全平方数
*
* */
public class SixtySeven {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
for (long i = n;; i++) {
if ((int) Math.sqrt(i) == Math.sqrt(i)) {
System.out.println(i);
break;
}
}
}
}
方法二:二分法
package _3_5_test;
import java.util.Scanner;
import _12_26_test.ten;
/*
手动撸一个算术平方根的方法
二分法的实现
*/
public class SixtySevenTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
long n = scanner.nextLong();
long result = 0;
out: for (long i = n;; i++) {
long a = 0;
long temp = 0;
long b = i;
// 取出一段数字中间的数字
while (a <= b) {
temp = (a + b) / 2;
if (temp * temp == i) {
result = i;
break out;
} else if (temp * temp > n) {
b = temp - 1;
} else if (temp * temp < n) {
a = temp + 1;
}
}
}
System.out.println(result);
}
}
效率比较:二分法节省了接近一半的时间