博弈题 poj 1143

来源:互联网 发布:浙江深孔钻编程招聘 编辑:程序博客网 时间:2024/05/01 09:25

#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
int const max_state = 1<<20;
int const maxn = 20;
int maxD, record[max_state], exp[maxn+1];
bool res[maxn+1];
int num, state;
int dfs(int curstate, int level){
    if(curstate == 0)
        return false;
    bool finalcan = false;
    int newstate, i, j, k;
    for(i = 0; i <= maxD-1;i++){
        if(curstate & exp[i]){
               newstate = curstate^exp[i];
               for(j = i + 2;j <= maxD;j++){
                   if((newstate & exp[j-1]) == 0)
                       continue;
                   for(k = 2; k <= j/2; k++){
                         if((newstate & exp[k-1]) == 0 && (newstate & exp[j - k -1]) == 0){
                              newstate = newstate^exp[j-1];
                              break;
                         }
                   }
               }
               int t;
               t = record[newstate];
               bool type;
               if(t == 1)
                    type = true;
               else if(t == 2)
                     type = false;
               else type = dfs(newstate, level+1);
               if(level == 1){
                   if(!type){
                       res[i] = true;
                       finalcan = true;
                       if(!record[curstate])  record[curstate] = 1;
                   }
               }
               else if(!type){
                   if(!record[curstate])  record[curstate] = 1;
                   return true;
               }
        }
    }
    if(level == 1){
        if(finalcan){
            if(!record[curstate])   record[curstate] = 1;
            return true;
        }
        else
        {
            if(!record[curstate])  record[curstate] = 2;
            return false;
        }
    }
    else {
        if(!record[curstate])   record[curstate] = 2;
        return false;
    }
}
int main(){
    freopen("input.txt", "r", stdin);
    int i, digit, ans = 1;
    exp[0] = 1;
    for(i = 1; i <= 20;i++)
        exp[i] = exp[i-1]*2;
    while(scanf("%d", &num)!=EOF){
        if(num == 0)
             break;
        memset(res, false, sizeof(res));
        maxD = -1;
        state = 0;
        for(i = 0; i < num; i++){
             scanf("%d", &digit);
             if(digit > maxD)
                 maxD = digit;
             state = state|exp[digit-1];
        }
        bool can = dfs(state, 1

        printf("Test Case #%d/n", ans++);
        if(!can)
             printf("There's no winning move./n");
        else
        {
            printf("The winning moves are:");
            for(i = 0 ; i < maxD; i++)
                   if(res[i])
                       printf(" %d", i+1);
            printf("/n");
        }
        printf("/n");
    }
    return 0;
}

原创粉丝点击