HDU 4101 Ali and Baba

长着一张博弈脸的搜索题。给出n*m的地图,有石头空地若干,还有一个宝藏。正整数表示石头的hp,0表示空地,-1表示宝藏,而且保证只有一个。AB轮流敲,每次从边界开始,选一个可达的石头,敲一下,石头的hp-1,hp为零就变成空地了。谁先敲到宝藏,谁赢。

如果从边界直接能走到宝藏,那么先手的A就赢了。否则呢,就会有一层石头保护着宝藏,谁先打破保护层,谁就输。所以保护层外的石头加上保护层边界上每个石头的hp-1就构成了他们能敲的石头总数。就是说把保护层边界上的各个点的hp都只剩下1。

5 7
0 1 1 1 1 1 0
1 0 0 0 0 0 1
1 0 0 0 -1 0 1
1 0 0 0 0 0 1
0 1 1 1 1 1 0
5 7
0 1 1 1 1 1 0
1 0 0 0 0 0 1
1 0 1 0 -1 0 1
1 0 0 0 0 0 1
0 1 1 1 1 1 0
5 7
0 1 1 1 1 1 0
1 0 0 0 0 0 1
1 0 2 0 -1 0 1
1 0 0 0 0 0 1
0 1 1 1 1 1 0

这三组数据改变了我企图一遍bfs的想法。

 

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<string>
#include<queue>
#include<cmath>
#include<map>
///LOOP
#define REP(i, n) for(int i = 0; i < n; i++)
#define FF(i, a, b) for(int i = a; i < b; i++)
#define FFF(i, a, b) for(int i = a; i <= b; i++)
#define FD(i, a, b) for(int i = a - 1; i >= b; i--)
#define FDD(i, a, b) for(int i = a; i >= b; i--)
///INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)
#define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)
#define RFI(n) scanf("%lf", &n)
#define RFII(n, m) scanf("%lf%lf", &n, &m)
#define RFIII(n, m, k) scanf("%lf%lf%lf", &n, &m, &k)
#define RFIV(n, m, k, p) scanf("%lf%lf%lf%lf", &n, &m, &k, &p)
#define RS(s) scanf("%s", s)
///OUTPUT
#define PN printf("\n")
#define PI(n) printf("%d\n", n)
#define PIS(n) printf("%d ", n)
#define PS(s) printf("%s\n", s)
#define PSS(s) printf("%s ", s)
#define PC(n) printf("Case %d: ", n)
///OTHER
#define PB(x) push_back(x)
#define CLR(a, b) memset(a, b, sizeof(a))
#define CPY(a, b) memcpy(a, b, sizeof(b))
#define display(A, n, m) {REP(i, n){REP(j, m)PIS(A[i][j]);PN;}}
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1

using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int MOD = 1e9+7;
const int INFI = 1e9 * 2;
const LL LINFI = 1e17;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int N = 333;
const int M = 888;
const int move[8][2] = {0, 1, 0, -1, 1, 0, -1, 0, 1, 1, 1, -1, -1, 1, -1, -1};

struct point
{
    int x, y;
    point(){};
    point(int a, int b){x = a, y = b;};
}p;
int a[N][N], vis[N][N];
int n, m, ans;
queue<point> q;

void bfs2()
{
    int tx, ty;
    while(!q.empty())q.pop();
    q.push(point(0, 0));
    while(!q.empty())
    {
        p = q.front();
        q.pop();
        REP(i, 4)
        {
            tx = p.x + move[i][0];
            ty = p.y + move[i][1];
            if(tx < 0 || ty < 0 || tx > n + 1 || ty > m + 1)continue;
            if(!vis[tx][ty])
            {
                vis[tx][ty] = 2;
                ans += a[tx][ty];
                q.push(point(tx, ty));
            }
            else if(vis[tx][ty] == 1)
            {
                vis[tx][ty] = 2;
                ans += (a[tx][ty] - 1);
            }
        }
    }
}

bool bfs()
{
    int tx, ty;
    while(!q.empty())
    {
        p = q.front();
        q.pop();
        REP(i, 4)
        {
            tx = p.x + move[i][0];
            ty = p.y + move[i][1];
            if(tx <= 0 || ty <= 0 || tx > n || ty > m)return 0;
            if(!vis[tx][ty])
            {
                vis[tx][ty] = 1;
                if(!a[tx][ty])q.push(point(tx, ty));
            }
        }
    }
    bfs2();
    return 1;
}

int main()
{
    //freopen("input.txt", "r", stdin);

    int x, y;
    while(RII(n, m) != EOF)
    {
        ans = 0;
        CLR(a, 0);
        CLR(vis, 0);
        FFF(i, 1, n)FFF(j, 1, m)
        {
            RI(a[i][j]);
            if(a[i][j] == -1)x = i, y = j;
        }
        while(!q.empty())q.pop();
        q.push(point(x, y));
        vis[x][y] = 1;
        if(bfs())puts((ans & 1) ? "Ali Win" : "Baba Win");
        else puts("Ali Win");
    }
    return 0;
}


 

 

posted on 2013-09-11 19:42  新一  阅读(153)  评论(0编辑  收藏  举报

导航