刷题——Meteor Shower POJ

来源:互联网 发布:嵌入式linux 快速启动 编辑:程序博客网 时间:2024/06/06 03:32
/*
从2滑到3用不大于10次的滑行到达
1为墙壁,0为可滑行区域
它会一直滑行直到碰到1,滑行出场地则终止
滑行碰到1时,碰撞的1会被变为0
求最小滑行次数
先把最小滑行次数设为11
从2开始,把2变为0,按以上规则进行遍历,最后滑行次数小于11则输出最小滑行次数,否则输出-1
*/
#include <stdio.h>
#include <string.h>
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
int min;
int a[25][25];
int n,m;
void dfs(int x,int y,int cnt){
    cnt++;
    if(cnt>10)return;
    for(int i=0;i<4;i++){
        int tx=x+dx[i];
        int ty=y+dy[i];
        if(tx>=0&&ty>=0&&tx<n&&ty<m){
            if(a[tx][ty]==1)continue;
            while(tx>=0&&ty>=0&&tx<n&&ty<m&&a[tx][ty]==0){
                tx+=dx[i];
                ty+=dy[i];
            }
            if(tx<0||ty<0||tx>=n||ty>=m)continue;
            if(a[tx][ty]==1){
                a[tx][ty]=0;
                dfs(tx-dx[i],ty-dy[i],cnt);
                a[tx][ty]=1;
                continue;
            }
            if(min>cnt){
                min=cnt;
            }
        }
    }
}
int main(){
    memset(a,-1,sizeof(-1));
    while(scanf("%d %d",&m,&n)&&(n||m)){
        int sx,sy;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                scanf("%d",&a[i][j]);
                if(a[i][j]==2){
                    sx=i,sy=j;
                }
            }
        }
        min=11;
        a[sx][sy]=0;
        dfs(sx,sy,0);
        if(min<11)printf("%d\n",min);
        else printf("-1\n");
    }
    return 0;
}