【BZOJ】3299: [USACO2011 Open]Corn Maze玉米迷宫(bfs)

http://www.lydsy.com/JudgeOnline/problem.php?id=3299

映射一下传送门即可。。

#include <cstdio>

#include <cstring>

#include <cmath>

#include <string>

#include <iostream>

#include <algorithm>

#include <queue>

using namespace std;

#define rep(i, n) for(int i=0; i<(n); ++i)

#define for1(i,a,n) for(int i=(a);i<=(n);++i)

#define for2(i,a,n) for(int i=(a);i<(n);++i)

#define for3(i,a,n) for(int i=(a);i>=(n);--i)

#define for4(i,a,n) for(int i=(a);i>(n);--i)

#define CC(i,a) memset(i,a,sizeof(i))

#define read(a) a=getint()

#define print(a) printf("%d", a)

#define dbg(x) cout << #x << " = " << x << endl

#define printarr2(a, b, c) for1(i, 1, b) { for1(j, 1, c) cout << a[i][j]; cout << endl; }

#define printarr1(a, b) for1(i, 1, b) cout << a[i]; cout << endl

inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }

inline const int max(const int &a, const int &b) { return a>b?a:b; }

inline const int min(const int &a, const int &b) { return a<b?a:b; }



const int N=1105, oo=~0u>>2, Q=N*N, dx[]={-1, 1, 0, 0}, dy[]={0, 0, -1, 1};

int mp[N][N], n, m, d[N][N], X, Y, XX, YY, front, tail;

struct dat { int x, y; }q[Q];

struct HS { int x[2], y[2]; }hs[51];



void bfs() {

	q[tail].x=X, q[tail++].y=Y;

	for1(i, 1, n) for1(j, 1, m) d[i][j]=oo;

	d[X][Y]=0;

	while(front!=tail) {

		dat &t=q[front++]; if(front==Q) front=0;

		int x=t.x, y=t.y;

		if(XX==x && YY==y) continue;

		rep(i, 4) {

			int fx=dx[i]+x, fy=dy[i]+y;

			if(fx<1 || fy<1 || fx>n || fy>m || mp[fx][fy]==1) continue;

			if(mp[fx][fy]>=4) {

				int h=mp[fx][fy], pos=(hs[h].x[0]==fx && hs[h].y[0]==fy);

				fx=hs[h].x[pos], fy=hs[h].y[pos];

			}

			if(d[fx][fy]>d[x][y]+1) {

				dat &t2=q[tail++]; if(tail==Q) tail=0;

				t2.x=fx, t2.y=fy; d[fx][fy]=d[x][y]+1;

			}

		}

	}

}



int main() {

	read(n); read(m);

	for1(i, 1, 50) CC(hs[i].x, 0), CC(hs[i].y, 0);

	for1(i, 1, n) for1(j, 1, m) {

		char ch=getchar(); while(ch=='\n' || ch=='\0') ch=getchar();

		if(ch=='#') mp[i][j]=1;

		else if(ch=='=') mp[i][j]=2, XX=i, YY=j;

		else if(ch=='@') mp[i][j]=3, X=i, Y=j;

		else if(ch>='A'&&ch<='Z') {

			int t=4+ch-'A', pos=(hs[t].x[0]!=0);

			hs[t].x[pos]=i; hs[t].y[pos]=j;

			mp[i][j]=t;

		}

	}

	bfs();

	print(d[XX][YY]);

	return 0;

}

 

 


 

 

Description

今年秋天,约翰带着奶牛们去玩玉米迷宫。迷宫可分成NxM个格子,有些格子种了玉 米,种宥玉米的格子无法通行。
迷宫的四条边界上都是种了玉米的格子,其屮只有一个格子 没种,那就是出口。
在这个迷宫里,有一些神奇的传送点6每个传送点由一对点组成,一旦 走入传送点的某个结点,
机器就会强制把你送到传送点的另一头去。所有的传送点都是双向 的,如果你定到了另一头,机器也会把你送回来。

奶牛在一个单位的时间内只能向相邻的四个方向移动一格,不过传送机传送是瞬间完成 的。
现在W西在迷宫里迷路了,她只知道目前的位罝在哪里,请你帮助她用最短的时间走出 迷宫吧。

Input

第一行:两个用空格分开的整数:N和M,2
第二行到N+1行:第i+1行有M个连续的字符,描述了迷宫第i行的信息。其中"#"代 表不能通行的玉米地,
"."代表可以通行的草地,"@"代表贝西的起始位罝,"="代表迷宫出口,
大写字母“A”到“Z”总是成对出现的,代表一对传送点

Output

 

第一行:一个整数,表示贝西走出迷宫的最短时间,保证逃离迷宮的路线一定存在

Sample Input


5 6
###=##
#.W.##
#.####
#.@W##
######

Sample Output

3

HINT

从起点向右走,通过w传送,再从另一端 走出迷宫

Source

你可能感兴趣的:(USACO)