POJ 1475 Pushing Boxes
搜索这样的东西仅仅要写之前规划得当还是蛮顺手的。
。
mark[x1][y1][x2][y2]表示小人在(x1,y1) 盒子在(x2,y2)这样的状态是否到过。
剩下的就是优先队列 + bfs 了。另外开一个栈记录前驱以输出路径。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-8) #define LL long long #define ULL unsigned long long #define _LL __int64 #define _INF 0x3f3f3f3f #define Mod 9999991 using namespace std; char Map[24][24]; int mark[22][22][22][22]; struct N { int x1,x2,y1,y2; }; struct Q { int ans,x1,y1,x2,y2,pre; int ans2,site; bool operator < (const Q &a)const{ return (a.ans2 < ans2 || (a.ans2 == ans2 && a.ans < ans)); } }q[200000]; bool Judge(Q f) { if(abs(f.x1-f.x2) + abs(f.y1-f.y2) <= 1) return true; return false; } int jx[] = {-1, 1, 0, 0}; int jy[] = { 0, 0,-1, 1}; void Out(int site,Q f) { if(site == -1) return ; Out(q[site].pre,q[site]); Q t = q[site]; if(t.x1 == f.x1) { if(t.y1+1 == f.y1) { if(t.x2 == f.x2 && t.y2+1 == f.y2) { printf("E"); } else { printf("e"); } } else if(t.y1-1 == f.y1) { if(t.x2 == f.x2 && t.y2-1 == f.y2) { printf("W"); } else { printf("w"); } } } else if(t.y1 == f.y1) { if(t.x1+1 == f.x1) { if(t.y2 == f.y2 && t.x2+1 == f.x2) { printf("S"); } else { printf("s"); } } else if(t.x1-1 == f.x1) { if(t.y2 == f.y2 && t.x2-1 == f.x2) { printf("N"); } else { printf("n"); } } } } void bfs(N s,int n,int m) { memset(mark,-1,sizeof(mark)); mark[s.x1][s.y1][s.x2][s.y2] = 0; priority_queue<Q> pq; Q f,t; int S = 0,E = 0; f.ans = 0; f.ans2 = 0; f.pre = -1; f.x1 = s.x1; f.x2 = s.x2; f.y1 = s.y1; f.y2 = s.y2; f.site = 0; q[E++] = f; pq.push(f); while(pq.empty() == false) { f = pq.top(); pq.pop(); if(Map[f.x2][f.y2] == 'T') { Out(f.pre,f); puts(""); return ; } t.pre = f.site; t.ans = f.ans+1; for(int i = 0 ;i < 4; ++i) { t.x1 = f.x1 + jx[i]; t.y1 = f.y1 + jy[i]; t.x2 = f.x2; t.y2 = f.y2; if(1 <= t.x1 && t.x1 <= n && 1 <= t.y1 && t.y1 <= m && Map[t.x1][t.y1] != '#' && -1 == mark[t.x1][t.y1][t.x2][t.y2]) { if(t.x1 != t.x2 || t.y1 != t.y2) { mark[t.x1][t.y1][t.x2][t.y2] = t.ans; t.site = E; t.ans2 = f.ans2; q[E++] = t; pq.push(t); } else { t.x2 = f.x2 + jx[i]; t.y2 = f.y2 + jy[i]; if(1 <= t.x2 && t.x2 <= n && 1 <= t.y2 && t.y2 <= m && Map[t.x2][t.y2] != '#' && -1 == mark[t.x1][t.y1][t.x2][t.y2]) { t.ans2 = f.ans2+1; t.site = E; q[E++] = t; pq.push(t); mark[t.x1][t.y1][t.x2][t.y2] = t.ans; } } } } } printf("Impossible.\n"); } int main() { int i,j,n,m; int icase = 1; while(scanf("%d %d",&n,&m) && (n||m)) { for(i = 1;i <= n;++i) scanf("%s",Map[i]+1); N s; for(i = 1;i <= n;++i) { for(j = 1;j <= m; ++j) { if(Map[i][j] == 'S') s.x1 = i,s.y1 = j; else if(Map[i][j] == 'B') s.x2 = i,s.y2 = j; } } printf("Maze #%d\n",icase++); bfs(s,n,m); puts(""); } return 0; }