1. 程式人生 > >HDU 2897 邂逅明下(巴什博弈變形)

HDU 2897 邂逅明下(巴什博弈變形)

                                     HDU 2897 邂逅明下

當日遇到月,於是有了明。當我遇到了你,便成了侶。 
那天,日月相會,我見到了你。而且,大地失去了光輝,你我是否成侶?這注定是個悽美的故事。(以上是廢話) 
小t和所有世俗的人們一樣,期待那百年難遇的日食。駐足街頭看天,看日月漸漸走近,小t的脖子那個酸呀(他堅持這個姿勢已經有半個多小時啦)。他低下仰起的頭,環顧四周。忽然發現身邊竟站著位漂亮的mm。天漸漸暗下,這mm在這街頭竟然如此耀眼,她是天使嗎?站著小t身邊的天使。 
小t對mm驚呼:“緣分吶~~”。mm卻毫不含糊:“是啊,500年一遇哦!”(此後省略5000字….) 
小t趕緊向mm要聯絡方式,可mm說:“我和你玩個遊戲吧,贏了,我就把我的手機號告訴你。”小t,心想天下哪有題目能難倒我呢,便滿口答應下來。mm開始說遊戲規則:“我有一堆硬幣,一共7枚,從這個硬幣堆裡取硬幣,一次最少取2枚,最多4枚,如果剩下少於2枚就要一次取完。我和你輪流取,直到堆裡的硬幣取完,最後一次取硬幣的算輸。我玩過這個遊戲好多次了,就讓讓你,讓你先取吧~” 
小t掐指一算,不對呀,這是不可能的任務麼。小t露出得意的笑:“還是mm優先啦,呵呵~”mm霎時愣住了,想是對小t的反應出乎意料吧。 
她卻也不生氣:“好小子,挺聰明呢,要不這樣吧,你把我的郵箱給我,我給你發個文字,每行有三個數字n,p,q,表示一堆硬幣一共有n枚,從這個硬幣堆裡取硬幣,一次最少取p枚,最多q枚,如果剩下少於p枚就要一次取完。兩人輪流取,直到堆裡的硬幣取完,最後一次取硬幣的算輸。對於每一行的三個數字,給出先取的人是否有必勝策略,如果有回答WIN,否則回答LOST。你把對應的答案發給我,如果你能在今天晚上8點以前發給我正確答案,或許我們明天下午可以再見。” 
小t二話沒說,將自己的郵箱給了mm。當他興沖沖得趕回家,上網看郵箱,哇!mm的郵件已經到了。他發現文字長達100000行,每行的三個數字都很大,但是都是不超過65536的整數。小t看錶已經下午6點了,要想手工算出所有結果,看來是不可能了。你能幫幫他,讓他再見到那個mm嗎? 

Input

不超過100000行,每行三個正整數n,p,q。

Output

對應每行輸入,按前面介紹的遊戲規則,判斷先取者是否有必勝策略。輸出WIN或者LOST。

Sample Input

7 2 4
6 2 4

Sample Output

LOST
WIN

看到取值範圍在p、q之間的時候,毫不猶豫的就寫了一個SG函式來解決問題(最初的SG【0】賦值為1,1~p之間的數的SG初始化值賦值為0表示必輸點)結果T了,看來這道題得找規律做,所以寫的對不對也不知道,先貼上來。


#include <bits\stdc++.h>
using namespace std;

int f[65537],sg[65537],vis[65537];

void getsg(int a,int b,int n)
{
    sg[0]=1;
    for(int i=1;i<=a;i++)
        sg[i]=0;
    for(int i=a+1;i<=n;i++)
    {
        memset(vis,0,sizeof(vis));
        for(int j=0;j<=b&&i>=f[j];j++)
        {
            vis[sg[i-f[j]]]=1;
        }
        for(int j=0;;j++)
            if(!vis[j])
        {
            sg[i]=j;
            break;
        }
    }
}

int main()
{
    int a,b,c;
    while(scanf("%d%d%d",&a,&b,&c)!=EOF)
    {
        int cont=0;
        for(int i=b;i<=c;i++,cont++)
            f[cont]=i;
        getsg(b,c-b,a);
        if(sg[a]) printf("WIN\n");
        else printf("LOST\n");
    }

    return 0;
}

然後題解發現其實巴什博弈的變形(取值有最小要求)也可以用與巴什博弈一樣的思路。其實應該叫巴什博弈的拓展,因為巴什博弈完全是適用於這個式子的(這裡暫時討論最先取完的人獲勝,與題目相反):n%(p+q)的值同p比較,若大於等於p或等於0,則後手必勝,若大於0且小於p則先手必勝(巴什博弈即令p=1)。

這道題的話,是反過來,先取完的人輸,那麼n%(p+q)的值同p比較,若大於p或等於0,則先手必勝,若大於0且小於等於p則後手必勝

在巴什博弈中,若先取完獲勝,則用(n-1)%(m+1)看是否等於0

若當前石子共有n =(p+q)* r個,則A必勝,必勝策略為:A第一次取q個,以後每次若B取K個,A取(p+q-k)個,如此下去最後必剩下p個給B,所以A必勝。


若n =(p+q)* r + left個(1< left <= p)B必勝,必勝策略為:每次取石子活動中,若A取k個,則B去(p+q-k)個,那麼最後剩下left個給A,此時left <= p,所以A只能一次去完,B勝。


若n =(p+q)* r + left個(p < left <= q),則A必勝,必勝策略為:A第一次取t(1<left – t <= p)個,以後每次B取k個,則A取(p+q-k)個,那麼最後留下1< left – t <=p給B,則A勝。

#include <bits\stdc++.h>
using namespace std;


int main()
{
    int a,b,c;
    while(scanf("%d%d%d",&a,&b,&c)!=EOF)
    {

        if(a%(b+c)<=b&&a%(b+c)>0) printf("LOST\n");
        else printf("WIN\n");
    }

    return 0;
}