做法:贪心

思路

  • 先判断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;
}