UVA 10404 – Bachet’s Game 組合博弈

來源:互聯網
上載者:User

             杭電劉春英老師的課件中有:

必敗點(P點) :前一個選手( Previous player)將取勝的位置稱為必敗點。 必勝點(N點) :下一個選手(Next player)將取勝的位置稱為必勝點。


步驟1:將所有終結位置標記為必敗點(P點); 步驟2: 將所有一步操作能進入必敗點(P點)的位置標記為必勝點(N點) 步驟3:如果從某個點開始的所有一步操作都只能進入必勝點(N點) ,則將該點標記為必敗點(P點) ; 步驟4: 如果在步驟3未能找到新的必敗(P點),則演算法終止;否則,返回到步驟2。

           按照這個類比步驟寫了個下面這個逾時的代碼

#include<cstdio>#include<iostream>#include<cstring>#include<set>#define MAXN 1000010using namespace std;int main(){    //freopen("in.txt","r",stdin);    set<int>win,lose;    bool vis[MAXN*2];    int n,m,p[11];    while(cin>>n>>m)    {        memset(vis,false,sizeof(vis));        win.clear();        lose.clear();        lose.insert(0);        vis[0]=true;        for(int i=0; i<m; i++)        {            int a;            cin>>a;            p[i]=a;            win.insert(a);            vis[a]=true;        }        int cur=0;        while(1)        {            if(vis[n])                break;            if(vis[cur])                cur++;            else            {                int flag=0;                for(int i=0; i<m; i++)                {                    if(cur>=p[i]&&!win.count(cur-p[i]))                    {                        flag=1;                        break;                    }                }                if(!flag)                {                    lose.insert(cur);                    vis[cur]=true;                    for(int i=0; i<m; i++)                    {                        win.insert(cur+p[i]);                        vis[cur+p[i]]=true;                    }                }                cur++;            }        }        if(win.count(n))            cout<<"Stan wins\n";        else cout<<"Ollie wins"<<endl;    }    return   0;}

          對於只剩i塊石頭時,i點要麼是必勝點,要麼是必敗點,如果有一個p[ ],使得i-p[ ]塊石頭是個必敗點,那麼i點是個必勝點,否則就是個必敗點。記憶化搜尋,下面是AC代碼:

#include<cstdio>#include<iostream>#include<cstring>#include<set>#define MAXN 1000010using namespace std;int main(){    //freopen("in.txt","r",stdin);    bool  f[1000010];    int p[11],m,n;    while(cin>>n>>m)    {        memset(f,false,sizeof(f));        for(int i=0; i<m; i++)        {            cin>>p[i];            f[p[i]]=true;        }        for(int i=1; i<=n; i++)        {            if(f[i]==true)  continue;            for(int j=0; j<m; j++)            {                if(i>=p[j]&&f[i-p[j]]==false)                {                    f[i]=true;                    break;                }            }        }        if(f[n]==true)            cout<<"Stan wins"<<endl;        else cout<<"Ollie wins"<<endl;    }    return   0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.