题意:2个人玩游戏, 每次轮到一个人选择一个比当前值小的素数, 然后在找到比素数的倍数中最小的并且不小于当前数的一个数。 现在这个游戏玩了2轮, 现在想找到最小的那个起点X0。
题解:我们可以发现样例解释中每次都是先减去最大的那个素数, 然后再从 减去后的数+1(如果不加一那么将导致通过这个素数发现最小的公倍数是减去数的本身) 到 n, 找到最小的那个值。因为要X0尽量小, 所以每一步都要能减去尽量大的数。 因为要找到最大的数, 所以我们先 素数塞跑出 当前值能找到最大的素数因子。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define ULL unsigned LL 5 #define fi first 6 #define se second 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 #define max3(a,b,c) max(a,max(b,c)) 10 const int INF = 0x3f3f3f3f; 11 const LL mod = 1e9+7; 12 typedef pair<int,int> pll; 13 const int N = 1e6+5; 14 int Find[N]; 15 int vis[N]; 16 void init(){ 17 for(int i = 2; i < N; i++){ 18 if(!vis[i]){ 19 Find[i] = -1; 20 for(int j = i*2; j < N; j += i) 21 vis[j] = 1, Find[j] = i; 22 } 23 } 24 } 25 int main(){ 26 int n; 27 scanf("%d", &n); 28 int ans = n; 29 init(); 30 for(int i = n - Find[n] + 1; i <= n; i++) 31 ans = min(ans, i-Find[i]+1); 32 printf("%d", ans); 33 return 0; 34 }