Alice and Bob begin their day with a quick game. They first choose a starting number X0 ≥ 3 and try to reach one million by the process described below.
Alice goes first and then they take alternating turns. In the i-th turn, the player whose turn it is selects a prime number smaller than the current number, and announces the smallest multiple of this prime number that is not smaller than the current number.
Formally, he or she selects a prime p < Xi - 1 and then finds the minimum Xi ≥ Xi - 1 such that p divides Xi. Note that if the selected prime palready divides Xi - 1, then the number does not change.
Eve has witnessed the state of the game after two turns. Given X2, help her determine what is the smallest possible starting number X0. Note that the players don't necessarily play optimally. You should consider all possible game evolutions.
The input contains a single integer X2 (4 ≤ X2 ≤ 106). It is guaranteed that the integer X2 is composite, that is, is not prime.
Output a single integer — the minimum possible X0.
为数不多的特别想写题解的题。
题意:定义一个规则:
一个数x0 找他的一个质因子p0 令 x1=(p0*k>=x0的第一个数)以此类推
问题是给你一个x2,让你找最小的x0
题解:
思考:x2什么样的质因子会让x1最小呢?
令f(x)为x的一个质因子
则通过这个质因子可以推导出x1的范围(x2-f(x2),x2]
这样一看,f(x2)最大,x1可能变成最小;
x1最小x0才有可能最小。
索性f(x)就定义成x的最大质因子
但是又一个问题出现了:怎么快速寻找一个数最大质因子呢?
想到了埃式筛法。
找到一个非素数时,将其标记上是哪个素数的倍数;
扫到最后所有非素数位置上存的就是最大质因子。
#include <bits/stdc++.h>
using namespace std;
int a[2000000];
int main(int argc, char const *argv[])
{
int n;
cin >> n;
for (int i = 2; i <= n; i++) {
if(!a[i]) {
for (int j = 2; j*i<=n; j++) {
a[j*i] = i;
}
}
}
int Min = 0x7fffffff;
for (int i = n-a[n]+1; i <= n; i++) {
Min = min(Min,i-a[i]+1);
}
cout << Min <<endl;
return 0;
}