解题思路
因为炮弹的落点在l-r之间,随机地点,所以我们只能在l–r之外选择,然后落点是成倍数增加,所以我们其实就是要去后面找到一个数满足下面条件:
不是l–r之间的数的倍数即可
然后可能的落点包括4中情况
1.安全点在n的右边
2.安全点在n的左边(当n比r大时)
3.安全点就是n
4.安全点在l前面一位
我们分解质因数后,因为分解出来的列表就是从小到大,所以我们遍历一下列表,如果为1那么肯定满足,因为他是一个质数,但是不长度不等于1,也有一种情况,就是当前数除以最小的因数,小于了l的值。即不是l–r的数之间的倍数,最后再和道l前一位的数比较一下就好
package com.xujialin.lanqiao;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @Author XuJiaLin
* @Date 2024/5/5 13:54
*/
public class lq36 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int l = scan.nextInt();
int r = scan.nextInt();
if (n < l) {
System.out.println(0);
return;
}
if (n == l) {
System.out.println(1);
return;
}
// 有4种情况,1.安全点在n的右边,2.安全点在n的左边(n比r大),3.安全点就是n,4.安全点在l前面一位
// 先计算在右边,和为n的情况
long res = 0, count = Math.max(n, r+1);
while (true) {
long l1 = get(count, l);
if (l1 != -1) {
res = count - n;
break;
}
count++;
}
// 计算左边的情况
count = n - 1;
while (count > r) {
long l1 = get(count, l);
if (l1 != -1) {
res = Math.min(n - count,res);
break;
}
count--;
}
// 最后计算是否比到l前一位更近一步
System.out.println(Math.min(res,n-l+1));
scan.close();
}
public static long get(long count, int l) {
List<Long> list = primeFactors(count);
if (list.size() == 1) {
return count;
} else {
for (Long aLong : list) {
if (count / aLong < l) {
return count;
} else {
break;
}
}
}
return -1;
}
public static List<Long> primeFactors(long n) {
List<Long> factors = new ArrayList<>();
// 将所有的 2 提取出来
while (n % 2 == 0) {
factors.add(2L);
n /= 2;
}
// n 现在应该是奇数,我们只需要检查奇数
for (long i = 3; i <= Math.sqrt(n); i += 2) {
while (n % i == 0) {
factors.add(i);
n /= i;
}
}
// 如果 n 是一个大于 2 的质数,那么添加 n 到结果列表中
if (n > 2) {
factors.add(n);
}
return factors;
}
}