码迷,mamicode.com
首页 > 其他好文 > 详细

HDU5724

时间:2016-07-30 15:01:03      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:


题意

一个 n * 20 的棋盘,棋盘上有若干棋子,Alice 和 Bob 轮流走,
每人每次可以选择任一行的一颗棋子向右移动到最近的一个空格 ;
也就是说如果右边与它相邻的格子里没有棋子,就移到右边与他相邻的格子去;
如果右边与它相邻的格子里 有棋子,就跳过它们移到相邻的空格 ;
一个空格只能放一颗棋子,且不能够放出去。
双方都采取最优策略,最后不能移动棋子的一方输 。

 

 

输入:
第一行输入 t ,表 t 组数据;
第二行输入 n ,表示 棋盘有 n 行;
接下来 n 行,每行包括 m (表示此行有 m 个棋子 )和 m 个数(棋子的位置)

 

输出:
若 Alice 赢,输出“YES” ,否则“NO”。

 

 

解题:

把它看成由 n 个子游戏组成的游戏, 那么整个游戏的 sg 值就是所有子游戏的 sg 值异或起来。
用二进制表示每一行的游戏局面 。 写完这题 感觉对状态压缩又多了解了一点点~~

(写的时候SB了一下,sg数组开小了= = 不造错哪又纠结了很久,不过也因为这样,想了很久这个问题,印象更深刻= =)

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
const int maxn = 1050000;
int num[25],sg[maxn];
void getsg()
{
    for(int i=1;i<(1<<20);i++)
    {
        int hash[50] = {0}, r=-1;
        for(int j=0;j<20;j++){
            if( !((i>>j) & 1)) r = j;
            if( (i>>j) & 1){
                if(r != -1)
                hash[ sg[i ^ (1<<j) ^ (1<<r)]] = 1;
            }
        }
        int j = 0;
        while(hash[j]!=0) j++;
        sg[i] = j; 
    }
}
int main()
{
    int t,n,m,loc; 
    getsg(); 
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n); 
        int ans = 0;
        for(int i=0;i<n;i++){
            scanf("%d",&m);   
            num[i] = 0;   
            for(int j=0;j<m;j++){
                scanf("%d",&loc);
                num[i] ^=  (1<<(20-loc));  
            }
            ans ^= sg[ num[i] ];
        }
        printf(ans?"YES\n":"NO\n");
    }
    return 0;
}

 

HDU5724

标签:

原文地址:http://www.cnblogs.com/ember/p/5720836.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!