USACO-Section2.4 Overfencing【深度优先搜索】

题目描述:

农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫。幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口。更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路。给定迷宫的宽W(1<=W<=38)及长H(1<=H<=100)。 2*H+1行,每行2*W+1的字符以下面给出的格式表示一个迷宫。然后计算从迷宫中最“糟糕”的那一个点走出迷宫所需的步数(就是从最“糟糕”的一点,走出迷宫的最少步数)。(即使从这一点以最优的方式走向最靠近的出口,它仍然需要最多的步数)当然了,牛们只会水平或垂直地在X或Y轴上移动,他们从来不走对角线。每移动到一个新的方格算作一步(包括移出迷宫的那一步)这是一个W=5,H=3的迷宫:

+-+-+-+-+-+
|         |
+-+ +-+ + +
|     | | |
+ +-+-+ + +
| |     |  
+-+ +-+-+-+
如上图的例子,栅栏的柱子只出现在奇数行或奇数列。每个迷宫只有两个出口。
-------------

INPUT FORMAT:

第一行: W和H(用空格隔开)
第二行至第2 * H + 1行: 每行2 * W + 1个字符表示迷宫

OUTPUT FORMAT:

输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。


SAMPLE INPUT
----------
5 3


+-+-+-+-+-+
|         |
+-+ +-+ + +
|     | | |
+ +-+-+ + +
| |     |  
+-+ +-+-+-+


SAMPLE OUTPUT
----------
9

解题思路:

注意迷宫的录入,如果一行迷宫后面全是空格则题目给的是回车。这题将迷宫的出口记为1,其他位置为INF,深度优先搜索即可。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h> 
#include<algorithm>  
using namespace std;
#define INF 999999
int W,H,maze[210][100]; 
int way[110][50][4];
int ans[110][50];
int x[4]={-1,0,1,0},y[4]={0,1,0,-1};
int answer=0;
int max(int a,int b){
    return a>b?a:b;
}
void dfs(int a,int b,int step){
    int k;
    for(int k=0;k<4;k++){
        int x1=a+x[k],y1=b+y[k];
        if(way[a][b][k]){
            if(ans[x1][y1]>step){
                ans[x1][y1]=step;
                dfs(x1,y1,step+1);
            }
        }   
    }
}
int main(){
    FILE *fin  = fopen ("maze1.in", "r");
    FILE *fout = fopen ("maze1.out", "w");
    int i,j;
    fscanf(fin,"%d%d\n",&W,&H);
    char a;
    for(i=0;i<2*H+1;i++){
        for(j=0;j<2*W+2;j++){
            fscanf(fin,"%c",&a);
            if(a=='\n')break;
            else maze[i][j]=a;
        }
    }
    for(i=0;i<H;i++){
        for(j=0;j<W;j++){
            ans[i][j]=INF;
        }
    }
    for(i=0;i<H;i++){
        for(j=0;j<W;j++){
            for(int k=0;k<4;k++){
                int x1=2*i+1+x[k],y1=2*j+1+y[k];
                if(maze[x1][y1]==' '||maze[x1][y1]==0){
                    if(x1==0||x1==2*H||y1==0||y1==2*W)ans[i][j]=1; 
                    else    way[i][j][k]=1;
                }   
            }
        }   
    }
    for(i=0;i<H;i++){
        for(j=0;j<W;j++){
            if(ans[i][j]==1)dfs(i,j,2);
        }
    }
    for(i=0;i<H;i++){
        for(j=0;j<W;j++){
            answer=max(ans[i][j],answer);
        }
    }
//  for(i=0;i<H;i++){
//      for(j=0;j<W-1;j++)
//          printf("%d ",ans[i][j]);
//      printf("%d\n",ans[i][j]);
//  }
    fprintf(fout,"%d\n",answer); 
    exit(0);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值