HRBUST - 2239 - 影子模仿术(bfs)
题目链接:https://vjudge.net/problem/HRBUST-2239
题目大意:和最基础的搜索差不多,只不过在lw移动的同时,pz会向相反方向移动(如果pz可以移动的话)
很有意思的搜索题,需要注意的是标记访问过的状态的时候要同时标记两个人的位置,因为lw移动的时候pz也可能会移动,这就导致lw在同一个位置的时候,由于先前的操作,pz不一定也在相同的位置,如果只标记lw的位置就有可能少搜索一些情况
#include<set> #include<map> #include<list> #include<stack> #include<queue> #include<cmath> #include<cstdio> #include<cctype> #include<string> #include<vector> #include<climits> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define endl '\n' #define rtl rt<<1 #define rtr rt<<1|1 #define lson rt<<1, l, mid #define rson rt<<1|1, mid+1, r #define maxx(a, b) (a > b ? a : b) #define minn(a, b) (a < b ? a : b) #define zero(a) memset(a, 0, sizeof(a)) #define INF(a) memset(a, 0x3f, sizeof(a)) #define IOS ios::sync_with_stdio(false) #define _test printf("==================================================\n") using namespace std; typedef long long ll; typedef pair<int, int> P; typedef pair<ll, ll> P2; const double pi = acos(-1.0); const double eps = 1e-7; const ll MOD = 1000000007LL; const int INF = 0x3f3f3f3f; const int _NAN = -0x3f3f3f3f; const double EULC = 0.5772156649015328; const int NIL = -1; template<typename T> void read(T &x){ x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } const int maxn = 30; int n, m, vis[maxn][maxn][maxn][maxn]; char mp[maxn][maxn]; int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; int rdir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; struct info { int cnt; int lx, ly; int px, py; }; inline bool checker(int x1, int y1, int x2, int y2) { return (abs(x1-x2) <= 1 && y1==y2) || (abs(y1-y2) <= 1 && x1==x2); //检查pz和lw是否相邻/在同一位置 } int bfs(int x1, int y1, int x2, int y2) { queue<info> qe; zero(vis); vis[x1][y1][x2][y2] = true; info t = {0, x1, y1, x2, y2}; qe.push(t); while(!qe.empty()) { t = qe.front(); qe.pop(); if (checker(t.lx, t.ly, t.px, t.py)) return t.cnt; ++t.cnt; for (int i = 0; i<4; ++i) { int xx = t.lx + dir[i][0], yy = t.ly + dir[i][1]; if (xx>=0 && xx<n && yy>=0 && yy<m && mp[xx][yy] != 'X') { info t2 = {t.cnt, xx, yy, t.px, t.py}; int xx2 = t2.px + rdir[i][0], yy2 = t2.py + rdir[i][1]; if (xx2>=0 && xx2<n && yy2>=0 && yy2<m && mp[xx2][yy2] != 'X') { t2.px = xx2, t2.py = yy2; //模拟pz移动 } if (!vis[xx][yy][t2.px][t2.py]) { qe.push(t2); vis[xx][yy][t2.px][t2.py] = true; } } } } return -1; } int main(void) { while(~scanf("%d%d", &n, &m)) { for (int i = 0; i<n; ++i) scanf("%s", mp[i]); P t1 = P(-1, -1), t2 = P(-1, -1); for (int i = 0; i<n; ++i) for (int j = 0; j<m; ++j) { if (mp[i][j] == 'L') t1 = P(i, j); else if (mp[i][j] == 'P') t2 = P(i, j); } P t3 = P(-1, -1); if (t1 == t3 || t2 == t3) { //如果两人在同一个点可能图中只有lw或者pz //这时候输出0就是了 printf("0\n"); continue; } int res = bfs(t1.first, t1.second, t2.first, t2.second); if (res == -1) printf("Smart PangZi!\n"); else printf("%d\n", res); } return 0; }