USACO Overfencing 穿越栅栏

63 篇文章 0 订阅
30 篇文章 0 订阅
 农夫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

这道题目,我实在是不想吐槽,我花了30分钟想正解,明显是dfs,又花了30分钟重构代码,整个就是一部血泪史,这题最主要的思想就是逆推,从出口向前推,然后注意一下解如何输出就可以了,特别要小心读入,一定不能一行读入一个回车,不然就会爆炸!

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int n,m;
int f[301][301];
char s[301][301];
void dfs(int i,int j,int sum){
    if(sum<f[i][j])f[i][j]=sum;
    else return;
    if(i>1 && s[i-1][j]==' ')dfs(i-1,j,sum+1);
    if(i<n && s[i+1][j]==' ')dfs(i+1,j,sum+1);
    if(j>1 && s[i][j-1]==' ')dfs(i,j-1,sum+1);
    if(j<m && s[i][j+1]==' ')dfs(i,j+1,sum+1);
}
int main(){
    freopen("overfencing.in","r",stdin);
    freopen("overfencing.out","w",stdout);
    int i,j,k;
    scanf("%d %d\n",&m,&n);
    m=m*2+1;n=n*2+1;
    memset(f,127,sizeof(f));
    for(i=1;i<=n;i++){
        for(j=1;j<=m+1;j++)
            scanf("%c",&s[i][j]);
    }
//  for(i=1;i<=n;i++){
//      for(j=1;j<=m;j++)
//          printf("%c",s[i][j]);
//      printf("\n");
//  }
    int ans=0;
    int chukou1i=0,chukou1j=0,chukou2i=0,chukou2j=0;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            if(i>1 && i<n && j>1 && j<m)continue;
            if(s[i][j]==' ' && !chukou2i){
                if(chukou1i){
                    chukou2i=i;chukou2j=j;
                }
                else{
                    chukou1i=i;chukou1j=j;
                }
            }
        }
        if(chukou2i)break;
    }
    dfs(chukou1i,chukou1j,0);
    dfs(chukou2i,chukou2j,0);
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++)
            if(s[i][j]==' '){
                if(ans<f[i][j])ans=f[i][j];
            }
    }
    printf("%d\n",(ans+1)/2);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值