hdu 4101 广搜

题意:n×m的棋盘上,0表示空格,可自由通过,-1表示宝石,正数k表示有一个值为k的石头,不能通过。两人轮流玩游戏,每次可以将一个从棋盘外围有路径可以到达的石头的值减1,若减为0则变为空格,可自由通过。问最后谁能拿到宝石。

分析:一开始以为是博弈,后来想想,发现如果甲将宝石外围的某石头(和宝石有路径相连的石头)变成了空格,则乙就能拿到宝石。所以他们只会选择和宝石不相通的石头,或者宝石外围的值大于1的石头。

于是先广搜一次,把宝石外围的石头标记一下。再从棋盘外围广搜,遇到石头,若是宝石外围的石头,则ans += val-1,val为石头的值。若是其它石头,ans += val。

为了方便,我在棋盘外围加了一圈空格,这样第二次搜索就可以从左上角开始,不用判断最外层哪些位置既可达又没有处理过。。。

 

 

const int M = 305;
int n,m;
int a[M][M],b[M][M];
LL cnt;

int x[M*M], y[M*M], p;
queue<int> q;

int flag;
void bfs1(int x1,int y1){
    while(!q.empty())q.pop();   p=0;
    x[p]=x1; y[p]=y1; q.push(p); p++;

    while(!q.empty()){
        int t=q.front(); q.pop();
        x1=x[t]; y1=y[t];
        FOR(i,0,4){
            int xx=x1+dx[i], yy=y1+dy[i];
            if(xx<1||xx>n||yy<1||yy>m){flag=true;return;}
            if(a[xx][yy]==0){
                a[xx][yy]=-1;
                x[p]=xx; y[p]=yy; q.push(p); p++;
            }else if(a[xx][yy]>0) b[xx][yy]=1;
        }
    }
}

void bfs2(){
    while(!q.empty())q.pop();   p=0;
    x[p]=0; y[p]=0; q.push(p); p++;

    while(!q.empty()){
        int t=q.front(); q.pop();
        int x1=x[t], y1=y[t];
        FOR(i,0,4){
            int xx=x1+dx[i], yy=y1+dy[i];
            if(xx<0||xx>n+1||yy<0||yy>m+1) continue;
            if(a[xx][yy]>=0){
                int temp=a[xx][yy]; a[xx][yy]=-2;
                if(b[xx][yy]) cnt+=temp-1;
                else {
                    cnt+=temp;
                    x[p]=xx; y[p]=yy; q.push(p); p++;

                }
            }
        }
    }
}

int main(){
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    #endif

    while(~scanf("%d%d",&n,&m)){
        int x, y;
        FOE(i,1,n) {
            FOE(j,1,m){
                scanf("%d",&a[i][j]);
                if(a[i][j]==-1){x=i;y=j;}
                b[i][j]=0;
            }
        }
        FOE(i,0,n+1) a[i][0]=a[i][m+1]=b[i][0]=b[i][m+1]=0;
        FOE(j,0,m+1) a[0][j]=a[n+1][j]=b[0][j]=b[n+1][j]=0;

        flag=false;
        bfs1(x,y);
        if(flag){printf("Ali Win\n");continue;}

        cnt=0;
        bfs2();
        if(cnt&1)   printf("Ali Win\n");
        else printf("Baba Win\n");
    }

    return 0;
}

 

posted @ 2013-05-10 19:02  心向往之  阅读(200)  评论(0)    收藏  举报