hdu 2873 Bomb Game(Sg函数)
题意:n*m个格子,有若干炸弹。对于在第一行或者第一列的炸弹,爆炸后会到那一行或者那一列的更前面(总的来说就是更靠近左上角)的位置。对于其他位置的炸弹,爆炸后会生成两个炸弹,分别到那一行的更前面或者那 一列的更前面。问先手是否有必赢策略。
大概明白了一点。整个游戏可以分为若干个炸弹的游戏的和,而实际上一个不在边界行或者列的炸弹,依然可以继续分,分成两个炸弹的和。而位于(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}