HDU5724 Chess
2016-07-19 21:34
302 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5724
个人感想:我感觉这就是我们弱校的差距啊,我在比赛的时候并没有做出来,都是听了我们实验室大牛说了我才写出来的,其实刚比赛我就想到用sg函数,怎么做?可是我知道得sg是状态转移..而且我手中又没sg的模板,,然后不会了,然后我看了一下那个数,才20!!肯定得用状压..然后..就没有然后了,好尴尬啊.
等大牛说了一下我就明白了:
SG+状压,通过状压,预处理所有情况的SG值!!具体怎么操作?我实在不太懂得表达了.我是看了《挑战程序设计竞赛》317页的模板然后我就联想到了怎么写,可是不能用set,一旦用set 整个算法要 多10多秒..我不知道什么情况,然后我通过暴力 找出sg的最大值,也不超过20,那么我直接用个数组标记访问过的sg就行了..我觉得我以后博弈可以直接上模板了.. 具体的看一下挑战吧.
分析:SG+状压
代码:
个人感想:我感觉这就是我们弱校的差距啊,我在比赛的时候并没有做出来,都是听了我们实验室大牛说了我才写出来的,其实刚比赛我就想到用sg函数,怎么做?可是我知道得sg是状态转移..而且我手中又没sg的模板,,然后不会了,然后我看了一下那个数,才20!!肯定得用状压..然后..就没有然后了,好尴尬啊.
等大牛说了一下我就明白了:
SG+状压,通过状压,预处理所有情况的SG值!!具体怎么操作?我实在不太懂得表达了.我是看了《挑战程序设计竞赛》317页的模板然后我就联想到了怎么写,可是不能用set,一旦用set 整个算法要 多10多秒..我不知道什么情况,然后我通过暴力 找出sg的最大值,也不超过20,那么我直接用个数组标记访问过的sg就行了..我觉得我以后博弈可以直接上模板了.. 具体的看一下挑战吧.
分析:SG+状压
代码:
/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * */ //#define OUT #include <iostream> using namespace std; #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <sstream> #include <cctype> #include <vector> #include <set> #include <cstdlib> #include <map> #include <queue> //#include<initializer_list> //#include <windows.h> //#include <fstream> //#include <conio.h> #define MaxN 0x7fffffff #define MinN -0x7fffffff #define Clear(x) memset(x,0,sizeof(x)) const int INF=0x3f3f3f3f; int T,t; int N; int n; int sum; int ans; const int maxn=1050000; int grundy[maxn];//sg值 bool F[25];//标记访问 int X[1005];//存下每行的状态 int getX(int x) { memset(F,false,sizeof(F)); for(int i=0;i<=19;i++) { if(x&(1<<i)) { int temp=x^(1<<i); bool flag=false; for(int j=i-1;j>=0;j--) { if(((1 << j)&temp)==0) { temp^=(1<<j); flag=true; break; } } if(flag)F[grundy[temp]]=true; } } int g=0; while(F[g])g++; return g; } void init() { int limited=(1<<20)-1; grundy[0]=0; for(int i=1;i<=limited;i++) { grundy[i]=getX(i); } } int main() { #ifdef OUT freopen("coco.txt","r",stdin); freopen("lala.txt","w",stdout); #endif init(); scanf("%d",&T); while(T--) { scanf("%d",&N); ans=0; for(int i=0;i<N;i++) { scanf("%d",&n); sum=0; while(n--) { scanf("%d",&t); sum|=(1<<(20-t)); } //ans^=grundy[sum]; X[i]=sum; } for(int i=0;i<N;i++) { ans^=grundy[X[i]]; } if(ans)printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- Windows下两个python版本怎么分别安装库
- Android百度地图(四)如何引入离线地图包
- pdo 连库
- 英语写作
- 新的开始
- Ol3中Map事件全解析
- C++函数中的那些坑
- c++父类和子类转化致命的代码错误
- 算法导论(5) 二叉搜索树
- 不同的域名指向同一个主机上的不同项目
- CSS的内联和块元素
- AndroidStudio给项目添加注解Butterknife8.7.0
- 几个常用(伪)汇编指令详解
- 在虚拟上安装kali
- 面试题42:翻转单词顺序 || 左旋字符串
- 京东618实践:一元抢宝系统的数据库架构优化
- 浏览器兼容
- dp 计数问题 复杂整数划分 区间dp
- java中的null和""区别
- post processing