C. 真假亚瑟王
题目描述
魔术师梅林在水晶球中预见了莫德雷德的叛逆,她决定在在莫德雷德叛逆之前采取一个有效的策略保护亚瑟王。
具体做法如下:使用魔法将亚瑟王复制成N份,当然,其中只有一个使真的。她认为这样就能有效的保护亚瑟王不被杀死。
为了自己能最终找到亚瑟王,她将所有的亚瑟王按1-N编号,并设定了一个密码数字X。真亚瑟王的编号是最接近N的且不能被2−X中任何一个数整除的数。(即真亚瑟王的编号的约数不再2−X中)。
输入
两个整数X,N,用一个空格隔开。
输出
真亚瑟王的编号。
样例输入
3 6
样例输出
5
样例输入
3 4
样例输出
1
样例输入
5 50
样例输出
49
提示
【数据范围】
对于30%的数据, 2 ≤ X ≤ N ≤ 10 2≤X≤N≤10 2≤X≤N≤10
对于60%的数据, 2 ≤ X ≤ N ≤ 1000 2≤X≤N≤1000 2≤X≤N≤1000
对于80%的数据, 2 ≤ X ≤ N ≤ 1 0 5 2≤X≤N≤10^5 2≤X≤N≤105
对于100%的数据, 2 ≤ X ≤ N ≤ 1 0 9 2≤X≤N≤10^9 2≤X≤N≤109
解决思路:分类讨论
提示:不合法代表一定不是答案,合法代表一定是答案。
已知:对于整数 n n n,小于等于 n n n且距离最近的素数离 n n n不会太远,所以直接暴力枚举,判断素数即可。
第一类: x 2 ≥ n x^2 \ge n x2≥n
1、因为一个合数肯定有一个小于等于根号的因子,所以小于等于 n n n的所有合数的最小因子必然在区间 [ 2 , x ] [2,x] [2,x]内,因此[ 2 , n ] 2,n] 2,n]的合数不合法。
2、 [ 2 , x ] [2,x] [2,x]的每个数不合法。
综上所述, [ x + 1 , n ] [x+1,n] [x+1,n]的素数可能合法。
暴力判断小于等于 n n n且距离最近的素数(前提是大于等于 x + 1 x+1 x+1或者大于 x x x)
若存在素数,输出素数。
若不存在素数,输出 1 1 1(由于 [ 2 , n ] [2,n] [2,n]中没有一个数合法,只剩下数字 1 1 1了)
第二类: x 2 < n x^2 < n x2<n
1、因为一个合数肯定有一个小于等于根号的因子,所以小于等于 x 2 x^2 x2的所有合数的最小因子必然在区间 [ 2 , x ] [2,x] [2,x]内,因此 [ 2 , x 2 ] [2,x^2] [2,x2]的合数不合法,但是 [ x 2 + 1 , n ] [x^2+1,n] [x2+1,n]的合数可能合法。
例如: x = 2 , n = 99 x=2,n=99 x=2,n=99时, 99 99 99合法但是是合数。
2、 [ x + 1 , n ] [x+1,n] [x+1,n]的素数可能合法。
综上所述,从 n n n开始往小于 n n n的数开始判断,如果这个数是素数或者它不是 [ 2 , x ] [2,x] [2,x]中任意数的倍数的话,输出这个数即可(直接枚举小于根号的因子判断是否在 [ 2 , x ] [2,x] [2,x]内)
#include
#include
#include
#include
#include
using namespace std;
#define mod 77797
typedef long long ll;
const int N = 2e1 + 10;
const ll INF = 0x3f3f3f3f3f3f3f3f;
bool judge(int n, int x) {
if (n == 1) return true;
if (n >= 2 && n <= x) return false;
for (int i = 2; i <= n / i; i++) {
if (n % i == 0) {
if (i <= x) return false;
}
}
return true;
}
bool isPrime(ll n) {
if (n == 1) return false;
for (int i = 2; i <= n / i; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
int main() {
ll x, n;
cin >> x >> n;
if (x * x >= n) {
while (n > x) {
if (isPrime(n)) {
cout << n << endl;
return 0;
}
n--;
}
cout << 1 << endl;
return 0;
}
else {
while (n) {
if (judge(n, x)) {
cout << n << endl;
return 0;
}
n--;
}
}
return 0;
}