1-2-K Game

傳送門

題意:給你兩個數,分別是n和k,每次操作你可以將n-1或者n-2或者n-k,誰不能再次進行操作就輸了;

題解:首先考慮當n<k時,由sg函數易知當n%3==0時,是先手1必敗態,然後當n==k時可以一次去完爲先手必勝,當n>k時,對於之後的數後繼狀態就會增加一個n-k,但是當k%3!=0時,對當前狀態沒有影響,當前狀態是3的倍數時,新增加的狀態必不可能是0,所以當前還是先手必敗,對於當前轉態不是3的倍數時,由於左邊的後繼狀態過來已經是先手必勝了,所以新增加的狀態對其沒有影響,當k是3的倍數時,在新增加的狀態就會對其產生影響,使其不爲0,所以就需要對k是3的倍數時的sg進行打表,通過1打表易得從k+1開始會有k/3-1個0 1 2和一個0 1 2 3,然後一直重複;

打表:

void getsg(int k){
    sg[0]=0;
    sg[1]=1;
    int fa[5];
    for(int a=2;a<k;a++)
        sg[a]=3-sg[a-1]-sg[a-2];
    for(int b=k;b<=3609;b++){
        memset(fa,0,sizeof(fa));
        fa[sg[b-1]]=1;
        fa[sg[b-2]]=1;
        fa[sg[b-k]]=1;
        sg[b]=0;
        while(fa[sg[b]])
            sg[b]++;
    }
    //for(int a=k+1;a<=3609;a++)
        //printf("%d\n",sg[a]);
}

AC代碼:

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<vector>
#include<iostream>
#include<math.h>
#define ll long long
using namespace std;
const int maxn=1e6+5;
const int maxn1=1e9;
int read(){
    int x=0,w=1;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')w=0,ch=getchar();
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
int sg[maxn];
void getsg(int k){
    sg[0]=0;
    sg[1]=1;
    int fa[5];
    for(int a=2;a<k;a++)
        sg[a]=3-sg[a-1]-sg[a-2];
    for(int b=k;b<=3609;b++){
        memset(fa,0,sizeof(fa));
        fa[sg[b-1]]=1;
        fa[sg[b-2]]=1;
        fa[sg[b-k]]=1;
        sg[b]=0;
        while(fa[sg[b]])
            sg[b]++;
    }
    //for(int a=k+1;a<=3609;a++)
        //printf("%d\n",sg[a]);
        printf("%d\n",sg[3609]);
}
int main( )
{
    /*while(1){
        int n=read();
        getsg(n);
    }*/
    //freopen("food.in","r",stdin);
	//freopen("food.out","w",stdout);
    int t=read();
    while(t--){
        int n=read(),k=read();
        if(n==k)
            printf("Alice\n");
        else if(k%3==0&&k<n){
            //printf("%d %d\n",n,k);
            int m=k/3;
            n=n-k-1;
            int num=(m-1)*3+4;
            n%=num;
            //printf("%d %d")
            if(n<=(m-1)*3){
                n%=3;
                if(n==0)
                    printf("Bob\n");
                else
                    printf("Alice\n");
            }
            else{
                n-=(m-1)*3;
                if(n==0)
                     printf("Bob\n");
                else
                    printf("Alice\n");
            }
        }
        else{
                //printf("1\n");
                n%=3;
                if(n==0)
                    printf("Bob\n");
                else
                    printf("Alice\n");
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章