http://acm.hdu.edu.cn/showproblem.php?pid=1760
题意:出处http://blog.csdn.net/qiqijianglu/article/details/7952261
题意:给你一个n*m的矩形,0表示空着的,1反之,现在两个人轮流放2*2的矩形,谁不能放了,谁就输了。
找sg值,可以选择暴力,也可以利用sg值的特点简化。
暴力就跟取石子一样,没什么差别,DFS搞定。把矩阵看成一个字符串,字符串就是一个状态。
其实我们也可以不暴力求sg值,因为只要当前状态能到达一个sg值为0的点,当前状态就是必胜点。
若当前点到达的所有状态都是必胜的,那么当前点就是必败点。所以当我们到达必胜点时,就必须转换当前状态继续递归找sg值。
法一、暴力找sg值:
表示还在理解中。。。。n
View Code
// I'm lanjiangzhou //C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> #include <time.h> //C++ #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <cctype> #include <stack> #include <string> #include <list> #include <queue> #include <map> #include <vector> #include <deque> #include <set> using namespace std; //*************************OUTPUT************************* #ifdef WIN32 #define INT64 "%I64d" #define UINT64 "%I64u" #else #define INT64 "%lld" #define UINT64 "%llu" #endif //**************************CONSTANT*********************** #define INF 0x3f3f3f3f // aply for the memory of the stack //#pragma comment (linker, "/STACK:1024000000,1024000000") //end int n,m; const int maxn =110; char s[maxn][maxn]; int a[maxn][maxn]; int mm[maxn][maxn]; int findset(int mm[maxn][maxn]){ for(int i=0;i<n-1;i++){ for(int j=0;j<m-1;j++){ if(mm[i][j]+mm[i+1][j]+mm[i][j+1]+mm[i+1][j+1]==0){ int tt[maxn][maxn]; for(int x=0;x<n;x++){ for(int y=0;y<m;y++){ tt[x][y]=mm[x][y]; } } tt[i][j]=tt[i+1][j]=tt[i][j+1]=tt[i+1][j+1]=1; if(findset(tt)==0) return 1; } } } return 0; } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ //getchar(); for(int i=0;i<n;i++){ scanf("%s",s[i]); for(int j=0;j<m;j++) a[i][j]=s[i][j]-'0'; } if(findset(a)) printf("Yes\n"); else printf("No\n"); } return 0; }