农夫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;
}