Overfencing 穿越栅栏

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

5 3
+-+-+-+-+-+
|         |
+-+ +-+ + +
|     | | |
+ +-+-+ + +
| |     |  
+-+ +-+-+-+ 

如上图的例子,栅栏的柱子只出现在奇数行或奇数列.每个迷宫只有两个出口。
INPUT FORMAT
第一行: W 和H(用空格隔开)
第二行至第2*H+2行: 每行2*W+1个字符表示迷宫
SAMPLE INPUT (file maze1.in)

5 3
+-+-+-+-+-+
|         |
+-+ +-+ + +
|     | | |
+ +-+-+ + +
| |     |  
+-+ +-+-+-+ 

OUTPUT FORMAT
输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。
SAMPLE OUTPUT (file maze1.out)
9

这一到题我的是思路是bfs从迷宫的出口进行BFS,选取的最小值,最后在两个循环找到最大值

代码如下:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
using namespace std;
int h,w,js=1,ans=0;
char a[500][500];
int bj[3],b[3],dj[10000],dj1[10000],dj2[10000];
int f[500][500],n,m;
bool l[500][500];
int fx[10]= {0,0,0,1,-1};
int fy[10]= {0,1,-1,0,0};
int bfs(int x,int y) {
    int head=0,tail=1;
    dj[1]=x;
    dj1[1]=y;
    dj2[1]=0;
    do {
        head++;
        for(int i=1; i<=4; i++) {
            x=dj[head]+fx[i];
            y=dj1[head]+fy[i];
            if(a[x][y]==' '&&x>0&&x<=n&&y>0&&y<=m&&l[x][y]==0) {//判断这点是不是在迷宫里面或为不为空格 
                tail++;
                f[x][y]=min(f[x][y],dj2[head]+1);//坐标为(x,y)的点到迷宫的最短路径 
                dj[tail]=x; 
                dj1[tail]=y;
                dj2[tail]=dj2[head]+1;
                l[x][y]=1;//标记坐标为(x,y)的点 
            }
        }
    } while(head<tail);//当头<尾时循环 
}
int main() {
    for(int i=1; i<=500; i++)
        for(int j=1; j<=500; j++)
            f[i][j]=10000;//把f数组赋一个很大的值 
    cin>>w>>h;//输入 
    char c;
    n=2*h+1;
    m=2*w+2;
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            scanf("%c",&a[i][j]);//字符输入 
            if((i==1||j==2||i==n||j==m)&&a[i][j]==' ') {//寻找迷宫出口 
                b[js]=i;//标记出口的坐标i 
                bj[js]=j;//标记出口的坐标j 
                js++;
            }
        }
    }
    int ja=0;
    for(int i=1; i<js; i++) {//枚举迷宫出口 
        memset(l,0,sizeof(l));//把l数组清空 
        bfs(b[i],bj[i]);//开始搜索 
    }
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            if(f[i][j]!=10000)
                ja=max(f[i][j],ja);
    cout<<(ja+1)/2;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值