华为OD机试 - RSA加密算法(Java 2024 E卷 100分)
long n = (long) Math.sqrt(num);
与long n = (long) Math.floor(Math.sqrt(num));
这两行代码的目的都是计算 num
的平方根,并将结果转换为 long
类型的整数。然而,它们在处理方式上有一些微小的差别。
long n = (long) Math.sqrt(num);
long n = (long) Math.floor(Math.sqrt(num));
区别分析
-
第一种写法:
(long) Math.sqrt(num);
Math.sqrt(num)
返回num
的平方根,结果是一个double
类型的浮点数。(long) Math.sqrt(num)
直接将这个double
类型的平方根结果转换为long
,这会截断小数部分,但不进行四舍五入。换句话说,它只保留整数部分,不管小数部分是多少。- 例如,如果
Math.sqrt(num)
的结果是5.9
,那么(long) Math.sqrt(num)
的结果就是5
。
-
第二种写法:
(long) Math.floor(Math.sqrt(num));
Math.sqrt(num)
同样计算num
的平方根,返回一个double
。Math.floor(Math.sqrt(num))
会将平方根结果向下取整,即使小数部分非常接近下一个整数,也会返回不大于该值的最大整数。- 然后
(long)
将这个向下取整的结果转换为long
类型。 - 在大多数情况下,与第一种写法的结果相同,但理论上更加明确,确保向下取整。
区别举例
假设 num = 36
:
Math.sqrt(36)
的结果是6.0
,两种写法都将n
设为6
。
假设 num = 35
:
Math.sqrt(35)
的结果是大约5.916
.(long) Math.sqrt(35)
会直接截断成5
。(long) Math.floor(Math.sqrt(35))
也会返回5
,因为Math.floor
将5.916
向下取整。
总结
虽然在大多数情况下两种写法的结果相同,但 Math.floor
确保了向下取整的意图更加明确,所以第二种写法通常更为严谨。
import java.util.*;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);long num = sc.nextLong();sc.close();long n = (long) Math.floor(Math.sqrt(num));String res = "-1 -1";for (long i = 2; i < n; ++ i) {if (num % i == 0) {long j = num / i;if (isPrime(i) && isPrime(j)) {if (i < j) {res = i + " " + j;} else {res = j + " " + i;}break;}}} System.out.println(res);} private static boolean isPrime(long n) {// TODOif (n < 2) {return false;}long sqrtN = (long) Math.floor(Math.sqrt(n));for (int i = 2; i < sqrtN; ++ i) {if (n % i == 0) {return false;}}return true;}
}