UESTC1712(Nim博弈)

七夜雪寂,一世人心

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

Nim遊戲是一種傳統的遊戲,其套路也漸漸被人熟悉,大家都不喜歡這種一眼就看出輸贏的遊戲,因此有人修改了Nim遊戲的規則:

1.這仍然是一個二人遊戲,有多堆石子,雙方輪流選取一堆從中拿走a個石子。

2.存在一個集合SSaa只能從集合SS中選取,第i個元素爲sisi.

衆所周知,一局比賽的輸贏是不能讓人信服的,所以需要多局的較量,所以雙方會進行mm場比賽,每場比賽的初始局勢都不同,然而dalao總是能看穿一切,當看到局勢的時候就知道了結果。

Input

第一行是一個數kk,表示集合SS的大小.

第二行是k個數表示集合中的元素。

第三行是一個數mm,表示有mm局比賽。

接下來是m行,每行第一個數mimi表示第i局初始有mimi堆石子,之後有mimi個數,代表每堆石子有h_i個。

(1k1001≤k≤100,1si100001≤si≤10000,1mi1001≤mi≤100,1hi100001≤hi≤10000)

Output

對於每一局,如果先手勝則輸出“win!”,後手勝則輸出“lose!”,每一局的輸出佔一行。

Sample input and output

Sample Input Sample Output
2 
2 5
3
2 5 12
3 2 4 7
4 2 3 7 12
lose!
win!
win!

Hint

By Qyitong

Source

2017 UESTC Training for Math
解題思路:經典Nim博弈,直接按題意打出sg表就行。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10000 + 10;
int inf = 0x3f3f3f3f;
int k;
int s[maxn];
int m;
int sg[maxn];
int Min;
set<int> g;
set<int>::iterator it;
void init()
{
    for(int i = 0; i < Min; i++) sg[i] = 0;
    for(int i = Min; i < maxn; i++)
    {
        g.clear();
        for(int j = 1; j <= k; j++)
        {
            if(i - s[j] >= 0) g.insert(sg[i - s[j]]);
        }
        int test = 0;
        for(it = g.begin(); it != g.end(); ++it)
        {
            int mm = *it;
            if(mm == test)
            {
                test++;
            }
            else break;
        }
        sg[i] = test;
    }
}
int main()
{
    scanf("%d", &k);
    Min = inf;
    for(int i = 1; i <= k; i++)
    {
        scanf("%d", &s[i]);
        Min = min(Min, s[i]);
    }
    init();
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &m);
        int h;
        int ans = 0;
        for(int i = 1; i <= m; i++)
        {
            scanf("%d", &h);
            ans ^= sg[h];
        }
        if(ans == 0) cout<<"lose!"<<endl;
        else cout<<"win!"<<endl;
    }
    return 0;
}


發佈了150 篇原創文章 · 獲贊 208 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章