hdu 2873 Bomb Game (二维sg打表)

来源:互联网 发布:首届全球程序员节 编辑:程序博客网 时间:2024/06/05 11:41

Bomb Game

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 609 Accepted Submission(s): 290

Problem Description
John and Jack, two mathematicians, created a game called “Bomb Game” at spared time. This game is played on an n*m chessboard. A pair of integers (p, q) represents the grid at row p, column q. Some bombs were placed on the chessboard at the beginning. Every round, a player can choose to explode a bomb located at (p, q), and the exploded bomb will disappear. Furthermore:

If two bombs located at the same position or a bomb located at (1, 1), they will be exploded automatically without producing new bombs.
Two players play in turn, until one player cannot explode the bombs and loses the game.
John always plays first.
Now, we’ll give you an initial situation, and you should tell us who will win at last. Assume John and Jack are smart enough, and they always do the best choice.

2 2
.#
..
2 2
.#
.#
0 0

Sample Output

John
Jack

题意:给你一个nm的棋盘,棋盘上会存在一些炸弹,每次可以选择引爆一颗炸弹,这个炸弹爆炸后会分成两个炸弹,分别到当前位置的上方和左方,如果处于边界则产生一个炸弹,且炸弹爆炸后会消失,谁不能引爆了谁输。

思路:我们将炸弹的位置当做石子堆的石子个数,我们首先看边界的情况,即只有一行或者一列的时候:假设当前炸弹处于(0,x),那么我们每次引爆可以任意选择一个位置,但是x是不断减小的,一直到0,因为每次只能向左引爆,且原炸弹消失,这样就转化成了x个石子,每次任意取的问题,此时sg[0][x]=x。当炸弹不在边界的时候,每次爆炸会产生两个炸弹,所以说又分成了两个子状态,我们只需要遍历标记这些子状态,即:x1i=0y1j=0sg[i][y]^sg[x][j].然后就按照普通求sg值的方法返回即可。

ac代码:

/* ***********************************************Author       : AnICoo1Created Time : 2016-08-09-09.39 TuesdayFile Name    : D:\MyCode\2016-8月\2016-8-9.cppLANGUAGE     : C++Copyright  2016 clh All Rights Reserved************************************************ */#include<stdio.h>#include<math.h>#include<string.h>#include<stack>#include<set>#include<map>#include<queue>#include<vector>#include<iostream>#include<algorithm>#define MAXN 1010000#define LL long long#define ll __int64#define INF 0xfffffff#define mem(x,y) memset(x,(y),sizeof(x))#define PI acos(-1)#define eps 1e-8using namespace std;ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}ll lcm(ll a,ll b){return a/gcd(a,b)*b;}ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}double dpow(double a,ll b){double ans=1.0;while(b){if(b%2)ans=ans*a;a=a*a;b/=2;}return ans;}//headchar str[110][110];int sg[110][110];int vis[3333];int getSG(int x,int y){    if(sg[x][y]!=-1) return sg[x][y];    mem(vis,0);    for(int i=0;i<x;i++)    {        for(int j=0;j<y;j++)        {            vis[getSG(x,j)^getSG(i,y)]=1;        }    }    for(int i=0;;i++)        if(!vis[i])        return i;}void  init(){    mem(sg,-1);    for(int i=0;i<55;i++)        sg[0][i]=sg[i][0]=i;    for(int i=0;i<55;i++)        for(int j=0;j<55;j++)            sg[i][j]=getSG(i,j);}int main(){    int n,m;init();    while(scanf("%d%d",&n,&m)!=EOF,n||m)    {        for(int i=0;i<n;i++) scanf("%s",str[i]);        int ans=0;        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)            {                if(str[i][j]=='#')                {                    ans^=sg[i][j];                }            }        }        if(ans) printf("John\n");        else printf("Jack\n");    }    return 0;}
0 0
原创粉丝点击