hdu 2873 Bomb Game(Sg函数)

hdu 2873题目链接

题意:n*m个格子,有若干炸弹。对于在第一行或者第一列的炸弹,爆炸后会到那一行或者那一列的更前面(总的来说就是更靠近左上角)的位置。对于其他位置的炸弹,爆炸后会生成两个炸弹,分别到那一行的更前面或者那 一列的更前面。问先手是否有必赢策略。

思路: 不会做2333 参考了 参考博客1 参考博客2

大概明白了一点。整个游戏可以分为若干个炸弹的游戏的和,而实际上一个不在边界行或者列的炸弹,依然可以继续分,分成两个炸弹的和。而位于(i.j)的炸弹,分成两个炸弹的和,有(i-1)*(j-1)种方案(这个不重要2333)

处于边界行或者列的点的sg值我们是可以知道的。。因为规则单一。。和移动等价。。

然后根据边界来进一步处理一般的情况。。

有点类似dp的思想。。。?

 1/* ***********************************************
 2Author :111qqz
 3Created Time :2016年07月23日 星期六 04时52分16秒
 4File Name :code/hdu/2873.cpp
 5************************************************ */
 6#include <cstdio>
 7#include <cstring>
 8#include <iostream>
 9#include <algorithm>
10#include <vector>
11#include <queue>
12#include <set>
13#include <map>
14#include <string>
15#include <cmath>
16#include <cstdlib>
17#include <ctime>
18#define fst first
19#define sec second
20#define lson l,m,rt<<1
21#define rson m+1,r,rt<<1|1
22#define ms(a,x) memset(a,x,sizeof(a))
23typedef long long LL;
24#define pi pair < int ,int >
25#define MP make_pair
26using namespace std;
27const double eps = 1E-8;
28const int dx4[4]={1,0,0,-1};
29const int dy4[4]={0,-1,1,0};
30const int inf = 0x3f3f3f3f;
31const int N=55;
32int n,m;
33int sg[N][N];
34bool vis[N*N];
35char maze[N][N];
36int px[N],py[N];
37void sg_init()
38{
39    ms(sg,0);
40    for ( int i = 0 ; i < N ; i++) //在边界的只能往一个方向生成炸弹,和移动了炸弹等价。
41	sg[i][0]=sg[0][i]=i;                       //还是0based好一点。。。这样(1,1)点的sg值自然就是0了。。。
42    for ( int i1 = 1 ; i1 < N ; i1++)
43	for ( int i2 = 1 ; i2 < N ; i2++)
44	{
45	    ms(vis,false);
46	    for ( int j1 =  0 ;  j1 < i1 ; j1++)
47		for ( int j2 = 0 ; j2 < i2 ; j2++)
48		    vis[sg[i1][j2]^sg[j1][i2]] = true;   //注意sg函数的变化规则。。其实是把一次爆炸考虑成两个爆炸的叠加,所以异或了。
49	    for ( int k = 0 ; ; k++)
50		if (!vis[k])
51		{   
52		    sg[i1][i2] = k;
53		    break;
54		}   
55	}
56}
57int main()
58{
59	#ifndef  ONLINE_JUDGE 
60	freopen("code/in.txt","r",stdin);
61  #endif
62	sg_init();
63//or ( int i = 0 ; i <= 10 ; i++)
64//   for ( int j = 0 ; j <= 10 ; j++)
65//cout<<"i:"<<i<<" j:"<<j<<" sgg[i][j]:"<<sg[i][j]<<endl;
66	while (~scanf("%d%d",&n,&m))
67	{
68	    if (n==0&&m==0) break;
69	    for ( int i = 0 ; i < n ; i++) scanf("%s",maze[i]);
70	    int sum  =  0 ;
71	    for ( int i = 0 ; i  < n ; i++)
72		for ( int j = 0 ; j < m ; j++)
73		    if (maze[i][j]=='#')
74		    {
75			    int tmp = sg[i][j];
76			    sum ^= tmp;
77		    }
78	    if  (sum)
79	    {
80		puts("John");
81	    }
82	    else
83	    {
84		puts("Jack");
85	    }
86	}
87  #ifndef ONLINE_JUDGE  
88  fclose(stdin);
89  #endif
90    return 0;
91}