做法:贪心
思路
- 先判断FFF和GGG谁能赢
- 再特判下第一轮能不能进行
- 如果FFF能赢,那么按照贪心的想法,FFF一定要取自己能取最多的数量,GGG一定要取自己能取最少的数量
即FFF拿走后剩下不小于n-k的最小的质数,GGG拿1个。如果FFF拿完后剩下1,2,3的数,GGG不能拿,游戏结束。 - 如果GGG能赢,那么按照贪心的想法,FFF一定要取自己能取最少的数量,GGG一定要取自己能取最多的数量
即FFF拿走后剩下小于n的最大的质数,GGG拿走后剩下大于n-k的最小的质数减1。如果FFF不能拿,游戏结束。
代码
// Problem: 质数与合数
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/problem/21350
// Memory Limit: 1048576 MB
// Time Limit: 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp(aa,bb) make_pair(aa,bb)
#define _for(i,b) for(int i=(0);i<(b);i++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,b,a) for(int i=(b);i>=(a);i--)
#define mst(abc,bca) memset(abc,bca,sizeof abc)
#define X first
#define Y second
#define lowbit(a) (a&(-a))
#define debug(a) cout<<#a<<":"<<a<<"\n"
typedef long long ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef long double ld;
const int N=4800000;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const double eps=1e-6;
const double PI=acos(-1.0);
int prime[N],cnt=0; //prime数组存放所以素数,cnt为素数个数
bool st[N]; //false为素数
void get_prime(int n){
for(int i=2;i<=n;i++){
if(!st[i]) prime[cnt++]=i; //把素数i存到prime数组中
for(int j=0;j<cnt&&i*prime[j]<=n;j++){
st[i*prime[j]]=true; //找到的素数的倍数不访问
if(i%prime[j]==0) break; //关键代码
}
}
}
bool flag=1;
void solve(){
int n,k;cin>>n>>k;
if(n==1||n==2){
cout<<"0\n";
return;
}
get_prime(n-1);
if(n-k>prime[cnt-1]){
cout<<"0\n";
return;
}
for(int i=cnt-1;i>=1;i--){
if(prime[i]-prime[i-1]>k+1) {
flag=0;
break;
}
}
int ans=0;
if(flag){
while(1){
int p=lower_bound(prime,prime+cnt,n-k)-prime;
ans++;
if(prime[p]<=3){ //GGG不能拿
cout<<ans<<"\n";
return;
}
n=prime[p]-1;
ans++;
}
}
while(1){
if(n-k<=prime[cnt-1]) n=prime[cnt-1];
else{
cout<<"-"<<ans<<"\n";
return;
}
ans++;
int p=upper_bound(prime,prime+cnt,n-k)-prime;
n=prime[p]-1;
cnt=p;
ans++;
}
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
// int t;cin>>t;while(t--)
solve();
return 0;
}