「NOIP模拟赛」栅栏迷宫
田野上搭建了一个黄金大神专用的栅栏围成的迷宫。幸运的是,在迷宫的边界上留出了两段栅栏作为迷宫的出口。更幸运的是,所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路。给定迷宫的宽W(1<=W<=38)及长H(1<=H<=100)。 2*H+1行,每行2*W+1的字符以下面给出的格式表示一个迷宫。然后计算从迷宫中最“糟糕”的那一个点走出迷宫所需的步数(就是从最“糟糕”的一点,走出迷宫的最少步数)。(即使从这一点以最优的方式走向最靠近的出口,它仍然需要最多的步数)当然了,黄金大神让你必须只会水平或垂直地在X或Y轴上移动,你不能从来不走对角线。每移动到一个新的方格算作一步(包括移出迷宫的那一步)这是一个W=5,H=3的迷宫:
+-+-+-+-+-+| |+-+ +-+ + +| | | |+ +-+-+ + +| | |+-+ +-+-+-+
如上图的例子,栅栏的柱子只出现在奇数行或奇数列。每个迷宫只有两个出口。
PROGRAM NAME: maze
INPUT FORMAT:
(file maze.in)
第一行: W和H(用空格隔开) 第二行至第2*H+1行: 每行2*W+1个字符表示迷宫
OUTPUT FORMAT:
(file maze.out)
输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。
SAMPLE INPUT
5 3+-+-+-+-+-+| |+-+ +-+ + +| | | |+ +-+-+ + +| | |+-+ +-+-+-+
SAMPLE OUTPUT
9
善良的学长:样例输入可以复制进记事本或者文本文档这样看起来更加直观!!!=v=
题解
奇怪的建图完bfs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #define pa pair<int,int> #define inf 1000000000 #define ll long long using namespace std; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,cnt,head,tail; string mp[205]; int id[105][105]; int q[10005],dis[10005],last[10005]; struct edge{int to,next;}e[40005]; void insert(int u,int v) { e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt; } void bfs() { dis[q[0]]=dis[q[1]]=1; while(tail!=head) { int now=q[head];head++; for(int i=last[now];i;i=e[i].next) if(dis[e[i].to]==-1) { dis[e[i].to]=dis[now]+1; q[tail++]=e[i].to; } } } int main() { //freopen("maze.in","r",stdin); //freopen("maze.out","w",stdout); memset(dis,-1,sizeof(dis)); n=read();m=read(); swap(n,m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) id[i][j]=(i-1)*m+j; for(int i=1;i<=2*n+1;i++) getline(cin,mp[i]); for(int i=1;i<=2*n+1;i++) mp[i]=" "+mp[i]; for(int i=1;i<=n;i++) { if(mp[2*i][1]==' '||!mp[2*i][1])q[tail++]=id[i][1]; if(mp[2*i][2*m+1]==' '||!mp[2*i][2*m+1])q[tail++]=id[i][m]; } for(int i=1;i<=m;i++) { if(mp[1][2*i]==' '||!mp[1][2*i])q[tail++]=id[1][i]; if(mp[2*n+1][2*i]==' '||!mp[2*n+1][2*i])q[tail++]=id[n][i]; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(j>1&&mp[2*i][2*j-1]==' ')insert(id[i][j],id[i][j-1]); if(j<m&&mp[2*i][2*j+1]==' ')insert(id[i][j],id[i][j+1]); if(i>1&&mp[2*i-1][2*j]==' ')insert(id[i][j],id[i-1][j]); if(i<n&&mp[2*i+1][2*j]==' ')insert(id[i][j],id[i+1][j]); } bfs(); int res=0; for(int i=1;i<=n*m;i++)res=max(res,dis[i]); printf("%d\n",res); return 0; } |