bfs+博弈 坑爹的hdu,用dfs会爆栈 只能用bfs了,用两边bfs 第一遍用来判断Ali能否一步找到财富,就是看外围是否有一条路通向(-1),再就是标记内边界,再就是第二遍从外面bfs来找寻真正的边界;其实这个题最终形态就是化为

5  1  5           0 1 0         

6  -1 6    ->   1 -1 1       

8  9  8           0 1 0         

当化为诸如此类的形态后 下一次攻击石头的人就会输,所以只要判一下外面石头的奇偶性就行了。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#define N 310

using std::vector;
using std::cout;
using std::endl;
int n,m;
int vis[N][N];
int map[N][N];
int a[N][N];
bool ok;
int sum,ans;
struct dat
{
    int nx,ny;
    void f(int x, int y)
    {
        nx=x,ny=y;
    }
} b,c;
vector<dat>p;
int move[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
void find(int s, int v)
{
    p.clear();
    b.f(s,v);
    p.push_back(b);
    int front=1,rear=0;
    while(rear<front)
    {
        c=p[rear++];
        if(c.nx==0 || c.nx==n-1 || c.ny==0 || c.ny==m-1)
        {
            ok=true;
            break;
        }
        for(int i=0; i<4; i++)
        {
            int x=c.nx+move[i][0];
            int y=c.ny+move[i][1];
            if(!vis[x][y] && !map[x][y] && x>=0 && x<n && y>=0 && y<m)
            {
                vis[x][y]=1;
                b.f(x,y);
                p.push_back(b);
                front++;
            }
            else if(!vis[x][y] && map[x][y]==2 && x>=0 && x<n && y>=0 && y<m)
            {
                map[x][y]=1;
                vis[x][y]=1;
            }
        }
    }
}
int bfsfind(int s, int v)
{
    p.clear();
    int front=1,rear=0;
    vis[s][v]=1;
    if(map[s][v]==2)
        sum+=a[s][v];
    else if(map[s][v]==1)
    {
        sum+=a[s][v]-1;
        return 0;
    }
    b.f(s,v);
    p.push_back(b);
    vis[s][v]=1;
    while(front>rear)
    {
        c=p[rear++];
        for(int i=0; i<4; i++)
        {
            int x=c.nx+move[i][0];
            int y=c.ny+move[i][1];
            if(!vis[x][y] && !map[x][y] && x>=0 && x<n && y>=0 && y<m)
            {
                vis[x][y]=1;
                b.f(x,y);
                p.push_back(b);
                front++;
            }
            else if(!vis[x][y] && map[x][y]==1 && x>=0 && x<n && y>=0 && y<m)
            {
                sum+=a[x][y]-1;
                vis[x][y]=1;
            }
            else if(!vis[x][y] && map[x][y]==2 && x>=0 && x<n && y>=0 && y<m)
            {
                sum+=a[x][y];
                vis[x][y]=1;
                b.f(x,y);
                p.push_back(b);
                front++;
            }
        }
    }
}
int main()
{
    while(scanf("%d %d",&n,&m)==2)
    {
        memset(map, 0, sizeof(map));
        int _x,_y;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; ++j)
            {
                scanf("%d",&a[i][j]);
                if(a[i][j]==-1)
                {
                    _x=i;
                    _y=j;
                    map[i][j]=3;
                }
                else if(a[i][j]>0)
                {
                    map[i][j]=2;
                }
            }
        }
        memset(vis, 0, sizeof(vis));
        ok=false;
        find(_x,_y);
        if(ok)
        {
            puts("Ali Win");
            continue;
        }
        ans=sum=0;
        memset(vis, 0, sizeof(vis));
        for(int i=0; i<n; i++)
            if(!vis[i][0])
                bfsfind(i,0);
        for(int i=0; i<n; i++)
            if(!vis[i][m-1])
                bfsfind(i,m-1);
        for(int j=0; j<m; ++j)
            if(!vis[0][j])
                bfsfind(0,j);
        for(int j=0; j<m; ++j)
            if(!vis[n-1][j])
                bfsfind(n-1,j);
        //cout << sum << endl;
        if(sum%2)
            puts("Ali Win");
        else puts("Baba Win");
    }
    return 0;
}
View Code

 

posted on 2013-09-25 20:44  风流monkey  阅读(233)  评论(0编辑  收藏  举报