专题一、简单搜索 - Virtual Judge
很久以前刷完了Virtual Judge上的简单搜索专题,现总结如下:
POJ 1321
由于题目的数据范围比较小,可以直接dfs暴力。读入时记录每个空位的位置,保存在pX[]以及pY[]数组中。暴力的时候统计当前处理第几个空格以及当前处理到了第几行即可。
#include <iostream> #include <memory.h> using namespace std; const int MAX = 128; long long ans; int N, K, nCnt; bool pUsed[MAX]; int pX[MAX], pY[MAX]; int pRow[MAX], pCol[MAX]; void dfs(int x, int y); int main() { char dwTmp; while(cin >> N >> K) { if(N == -1 && K == -1) { break; } nCnt = 0; ans = 0; for(int i = 1; i <= N; i++) { for(int j = 1; j <= N; j++) { cin >> dwTmp; if(dwTmp == '#') { nCnt++; pX[nCnt] = i; pY[nCnt] = j; } } cin.ignore(); } memset(pRow, 0, sizeof(pRow)); memset(pCol, 0, sizeof(pCol)); memset(pUsed, false, sizeof(pUsed)); dfs(1, 0); cout << ans << endl; } return 0; } void dfs(int x, int y) { if(y == K) { ans++; } else { for(int i = x; i <= nCnt; i++) { if(!(pUsed[i] || pRow[pX[i]] || pCol[pY[i]])) { pRow[pX[i]]++; pCol[pY[i]]++; pUsed[i] = true; dfs(i + 1, y + 1); pUsed[i] = false; pRow[pX[i]]--; pCol[pY[i]]--; } } } }
POJ 2251
这是一个三维迷宫,对立体空间的六个方向进行bfs即可。
#include <iostream> #include <memory.h> #include <string> #include <queue> using namespace std; const int MAX = 32; const int dx[] = { 1, -1, 0, 0, 0, 0 }; const int dy[] = { 0, 0, 1, -1, 0, 0 }; const int dz[] = { 0, 0, 0, 0, 1, -1 }; struct Point { Point(int _x = 0, int _y = 0, int _z = 0, int _ans = 0) { x = _x; y = _y; z = _z; ans = 0; } int x, y, z, ans; }; queue<Point> Q; Point Start, End; int pMaze[MAX][MAX][MAX]; bool pVisited[MAX][MAX][MAX]; int main() { int L, R, C; string strTmp; while(cin >> L >> R >> C) { if(L == 0 && R == 0 && C == 0) { break; } while(!Q.empty()) { Q.pop(); } for(int i = 1; i <= L; i++) { for(int j = 1; j <= R; j++) { cin >> strTmp; for(int k = 1; k <= C; k++) { if(strTmp[k - 1] == 'S') { pMaze[i][j][k] = 0; Start = Point(i, j, k); } else if(strTmp[k - 1] == 'E') { pMaze[i][j][k] = 0; End = Point(i, j, k); } else if(strTmp[k - 1] == '.') { pMaze[i][j][k] = 0; } else if(strTmp[k - 1] == '#') { pMaze[i][j][k] = 1; } } } } Q.push(Start); bool bFlag = false; memset(pVisited, false, sizeof(pVisited)); pVisited[Start.x][Start.y][Start.z] = true; while(!Q.empty()) { Point Now = Q.front(); Q.pop(); if(Now.x == End.x && Now.y == End.y && Now.z == End.z) { cout << "Escaped in " << Now.ans << " minute(s)." << endl; bFlag = true; break; } for(int i = 0; i < 6; i++) { Point Next; Next.x = Now.x + dx[i]; Next.y = Now.y + dy[i]; Next.z = Now.z + dz[i]; Next.ans = Now.ans + 1; if(Next.x >= 1 && Next.x <= L && Next.y >= 1 && Next.y <= R && Next.z >= 1 && Next.z <= C && pMaze[Next.x][Next.y][Next.z] == 0 && !pVisited[Next.x][Next.y][Next.z]) { pVisited[Next.x][Next.y][Next.z] = true; Q.push(Next); } } } if(!bFlag) { cout << "Trapped!" << endl; } } return 0; }
POJ 3278
同样是bfs,一共三种状态进行转移。
#include <iostream> #include <memory.h> #include <queue> using namespace std; const int MAX = 1024000; struct Pos { Pos(int _x = 0, int _ans = 0) { x = _x; ans = _ans; } int x, ans; }; queue<Pos> Q; bool pVisited[MAX]; int main() { int N, K; while(cin >> N >> K) { memset(pVisited, false, sizeof(pVisited)); while(!Q.empty()) { Q.pop(); } Q.push(Pos(N, 0)); pVisited[N] = true; while(!Q.empty()) { Pos Now = Q.front(); Q.pop(); if(Now.x == K) { cout << Now.ans << endl; break; } if(Now.x * 2 >= 0 && Now.x * 2 < MAX && !pVisited[Now.x * 2]) { Q.push(Pos(Now.x * 2, Now.ans + 1)); pVisited[Now.x * 2] = true; } if(Now.x - 1 >= 0 && Now.x - 1 < MAX && !pVisited[Now.x - 1]) { Q.push(Pos(Now.x - 1, Now.ans + 1)); pVisited[Now.x - 1] = true; } if(Now.x + 1 >= 0 && Now.x + 1 < MAX && !pVisited[Now.x + 1]) { Q.push(Pos(Now.x + 1, Now.ans + 1)); pVisited[Now.x + 1] = true; } } } return 0; }
POJ 3279
考虑到第一行的状态确定以后,后面的N - 1行的状态就确定了,因此只需要枚举第一行,由于数据范围比较小,所以使用二进制状态压缩即可。
#include <iostream> #include <memory.h> using namespace std; const int MAX = 32; const int dx[] = { 1, -1, 0, 0 }; const int dy[] = { 0, 0, 1, -1 }; int M, N; int pMap[MAX][MAX]; int pAns[MAX][MAX], pTmp[MAX][MAX]; int Solve(); int IsFlip(int x, int y); int main() { while(cin >> M >> N) { int ans = 2147483647; for(int i = 1; i <= M; i++) { for(int j = 1; j <= N; j++) { cin >> pMap[i][j]; } } for(int i = 0; i < (1 << N); i++) { memset(pTmp, 0, sizeof(pTmp)); for(int j = 1; j <= N; j++) { if(i & (1 << j - 1)) { pTmp[1][j] = 1; } } int nTmp = Solve(); if(nTmp == -1) { continue; } if(nTmp < ans) { ans = nTmp; memcpy(pAns, pTmp, sizeof(pTmp)); } } if(ans != 2147483647) { for(int i = 1; i <= M; i++) { for(int j = 1; j <= N; j++) { cout << pAns[i][j]; if(j != N) { cout << " "; } } cout << endl; } } else { cout << "IMPOSSIBLE" << endl; } } return 0; } int Solve() { int nRet = 0; for(int i = 2; i <= M; i++) { for(int j = 1; j <= N; j++) { if(IsFlip(i - 1, j)) { pTmp[i][j] = 1; } } } for(int i = 1; i <= N; i++) { if(IsFlip(M, i)) { return -1; } } for(int i = 1; i <= M; i++) { for(int j = 1; j <= N; j++) { nRet += pTmp[i][j]; } } return nRet; } int IsFlip(int x, int y) { int nRet = pTmp[x][y]; for(int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if(nx >= 1 && nx <= M && ny >= 1 && ny <= N) { nRet += pTmp[nx][ny]; } } nRet += pMap[x][y]; return nRet & 1; }
POJ 1426
这道题目也是一道bfs,只需要记录每次遍历到的结果tmp % N,同时保存已选取的数字的内容,最后判断已选取的数字的长度是否符合题目的要求。
#include <iostream> #include <memory.h> #include <string> #include <queue> using namespace std; const int MAX = 256; const int d[] = { 0, 1 }; struct Num { Num(int _nNum = 1, string _ans = "1") { nNum = _nNum; ans = _ans; } int nNum; string ans; }; int N; bool pVisited[MAX]; queue<Num> Q; int main() { while(cin >> N) { if(N == 0) { break; } else { while(!Q.empty()) { Q.pop(); } memset(pVisited, false, sizeof(pVisited)); Q.push(Num(1)); pVisited[1 % N] = true; while(!Q.empty()) { Num Now = Q.front(); Q.pop(); if(Now.nNum % N == 0) { cout << Now.ans << endl; break; } for(int i = 0; i < 2; i++) { Num Next = Now; if(!pVisited[(Now.nNum * 10 + d[i]) % N]) { pVisited[(Now.nNum * 10 + d[i]) % N] = true; Q.push(Num((Now.nNum * 10 + d[i]) % N, Now.ans + (char)(d[i] + '0'))); } } } } } return 0; }
POJ 3126
bfs水题。
#include <iostream> #include <memory.h> #include <string> #include <queue> #include <set> using namespace std; const int MAX = 10240; struct Prime { Prime(int _x = 0, int _ans = 0) { x = _x; ans = _ans; } int x, ans; }; set<int> S; queue<Prime> Q; bool pVisited[MAX]; int Change(int x, int y, int z); int main() { for(int i = 1000; i <= 9999; i++) { bool bFlag = true; for(int j = 2; j * j <= i; j++) { if(i % j == 0) { bFlag = false; } } if(bFlag) { S.insert(i); } } int N, s, e; while(cin >> N) { for(int i = 1; i <= N; i++) { while(!Q.empty()) { Q.pop(); } memset(pVisited, false, sizeof(pVisited)); cin >> s >> e; Q.push(Prime(s, 0)); pVisited[s] = true; while(!Q.empty()) { Prime Now = Q.front(); Q.pop(); if(Now.x == e) { cout << Now.ans << endl; break; } for(int i = 0; i < 4; i++) { for(int j = 0; j <= 9; j++) { int nNext = Change(Now.x, i, j); if(S.count(nNext) && !pVisited[nNext]) { Q.push(Prime(nNext, Now.ans + 1)); pVisited[nNext] = true; } } } } } } return 0; } int Change(int x, int y, int z) { int nTmp = 1; while(y--) { nTmp *= 10; } x -= x / nTmp % 10 * nTmp; x += z * nTmp; return x; }
POJ 3087
模拟整个过程即可,如果出现与初始情况相同的情形,就说明无解。
#include <iostream> #include <string> using namespace std; int main() { int N, C; bool bFlag; string SA, SB, S, Init; cin >> N; for(int i = 1; i <= N; i++) { cin >> C >> SA >> SB >> S; int nCnt = 0; Init = ""; bFlag = false; while(1) { nCnt++; string ans = ""; for(int j = 0; j < SA.size(); j++) { ans += SB[j]; ans += SA[j]; } if(Init == "") { Init = ans; } SA = ans.substr(0, C); SB = ans.substr(C, C); if(nCnt != 1 && ans == Init) { break; } if(ans == S) { cout << i << " " << nCnt << endl; bFlag = true; break; } } if(!bFlag) { cout << i << " -1" << endl; } } return 0; }
POJ 3414
bfs水题。处理好倒水的过程即可。
#include <iostream> #include <memory.h> #include <string> #include <queue> using namespace std; const int MAX = 128; struct Pots { Pots(int _A = 0, int _B = 0) { A = _A; B = _B; while(!pOpt.empty()) { pOpt.pop(); } } int A, B; queue<string> pOpt; }; int A, B, C; bool pVisited[MAX][MAX]; queue<Pots> Q; Pots Opt(Pots Now, int k); Pots Fill(Pots Now, int x); Pots Drop(Pots Now, int x); Pots Pour(Pots Now, int x); int main() { bool bFlag; while(cin >> A >> B >> C) { bFlag = false; while(!Q.empty()) { Q.empty(); } memset(pVisited, false, sizeof(pVisited)); Q.push(Pots(0, 0)); pVisited[0][0] = true; while(!Q.empty()) { Pots Now = Q.front(); Q.pop(); if(Now.A == C || Now.B == C) { cout << Now.pOpt.size() << endl; while(!Now.pOpt.empty()) { cout << Now.pOpt.front() << endl; Now.pOpt.pop(); } bFlag = true; break; } for(int i = 0; i < 6; i++) { Pots Next = Opt(Now, i); if(!pVisited[Next.A][Next.B]) { Q.push(Next); pVisited[Next.A][Next.B] = true; } } } if(!bFlag) { cout << "impossible" << endl; } } return 0; } Pots Opt(Pots Now, int k) { switch(k) { case 0: return Fill(Now, 0); case 1: return Fill(Now, 1); case 2: return Drop(Now, 0); case 3: return Drop(Now, 1); case 4: return Pour(Now, 0); case 5: return Pour(Now, 1); } } Pots Fill(Pots Now, int x) { if(x == 0) { Now.A = A; Now.pOpt.push("FILL(1)"); } else { Now.B = B; Now.pOpt.push("FILL(2)"); } return Now; } Pots Drop(Pots Now, int x) { if(x == 0) { Now.A = 0; Now.pOpt.push("DROP(1)"); } else { Now.B = 0; Now.pOpt.push("DROP(2)"); } return Now; } Pots Pour(Pots Now, int x) { if(x == 0) { Now.B += Now.A; if(Now.B > B) { Now.A = Now.B - B; Now.B = B; } else { Now.A = 0; } Now.pOpt.push("POUR(1,2)"); } else { Now.A += Now.B; if(Now.A > A) { Now.B = Now.A - A; Now.A = A; } else { Now.B = 0; } Now.pOpt.push("POUR(2,1)"); } return Now; }
FZU 2150
暴力枚举两个起点,然后bfs。
#include <iostream> #include <memory.h> #include <string> #include <queue> using namespace std; const int MAX = 16; const int dx[] = { 1, -1, 0, 0 }; const int dy[] = { 0, 0, 1, -1 }; struct Pos { Pos(int _x, int _y, int _ans) { x = _x; y = _y; ans = _ans; } int x, y, ans; }; int T, N, M; int pMap[MAX][MAX]; bool pVisited[MAX][MAX]; queue<Pos> Q; bool Check(); int Bfs(Pos A, Pos B); int main() { string strTmp; cin >> T; for(int k = 1; k <= T; k++) { cin >> N >> M; int ans = 2147483647; bool bFlag = false; for(int i = 1; i <= N; i++) { cin >> strTmp; for(int j = 1; j <= M; j++) { if(strTmp[j - 1] == '.') { pMap[i][j] = 1; } else { pMap[i][j] = 0; } } } for(int i = 1; i <= N; i++) { for(int j = 1; j <= M; j++) { for(int p = 1; p <= N; p++) { for(int q = 1; q <= M; q++) { if(pMap[i][j] || pMap[p][q]) { continue; } int nTmp = Bfs(Pos(i, j, 0), Pos(p, q, 0)); if(Check()) { ans = min(ans, nTmp); bFlag = true; } } } } } cout << "Case " << k << ": "; if(bFlag) { cout << ans << endl; } else { cout << -1 << endl; } } return 0; } int Bfs(Pos A, Pos B) { int nRet = 0; while(!Q.empty()) { Q.pop(); } memset(pVisited, false, sizeof(pVisited)); Q.push(A); pVisited[A.x][A.y] = true; Q.push(B); pVisited[B.x][B.y] = true; while(!Q.empty()) { Pos Now = Q.front(); Q.pop(); nRet = max(nRet, Now.ans); for(int i = 0; i < 4; i++) { Pos Next = Now; Next.ans++; Next.x += dx[i]; Next.y += dy[i]; if(Next.x >= 1 && Next.x <= N && Next.y >= 1 && Next.y <= M && !pVisited[Next.x][Next.y] && !pMap[Next.x][Next.y]) { Q.push(Next); pVisited[Next.x][Next.y] = true; } } } return nRet; } bool Check() { for(int i = 1; i <= N; i++) { for(int j = 1; j <= M; j++) { if(!pMap[i][j] && !pVisited[i][j]) { return false; } } } return true; }
UVa 11624
注意可能有多个点起火,设定一个全局时间量,用来控制人以及火的运动顺序,先处理火,再处理人。然后就是bfs水题。
#include <iostream> #include <memory.h> #include <queue> using namespace std; const int MAX = 1024; const int dx[] = { 1, -1, 0, 0 }; const int dy[] = { 0, 0, 1, -1 }; struct Pos { Pos(int _x = 0, int _y = 0, int _ans = 0) { x = _x; y = _y; ans = _ans; } int x, y, ans; }; int T, R, C; int pMap[MAX][MAX]; bool pVJ[MAX][MAX], pVF[MAX][MAX]; queue<Pos> J, F; int main() { string strTmp; cin >> T; for(int k = 1; k <= T; k++) { cin >> R >> C; bool bFlag = false; while(!J.empty()) { J.pop(); } while(!F.empty()) { F.pop(); } memset(pVJ, false, sizeof(pVJ)); memset(pVF, false, sizeof(pVF)); for(int i = 1; i <= R; i++) { cin >> strTmp; for(int j = 1; j <= C; j++) { if(strTmp[j - 1] == '#') { pMap[i][j] = 1; } else { pMap[i][j] = 0; } if(strTmp[j - 1] == 'J') { J.push(Pos(i, j)); pVJ[i][j] = true; } if(strTmp[j - 1] == 'F') { F.push(Pos(i, j)); pVF[i][j] = true; } } } int nTime = 0; while(!J.empty()) { while(!F.empty() && F.front().ans <= nTime) { Pos FN = F.front(); F.pop(); for(int i = 0; i < 4; i++) { Pos Next = FN; Next.ans++; Next.x += dx[i]; Next.y += dy[i]; if(Next.x >= 1 && Next.x <= R && Next.y >= 1 && Next.y <= C && !pMap[Next.x][Next.y] && !pVF[Next.x][Next.y]) { F.push(Next); pVF[Next.x][Next.y] = true; } } } while(!J.empty() && J.front().ans <= nTime) { Pos JN = J.front(); J.pop(); if(JN.x == 1 || JN.x == R || JN.y == 1 || JN.y == C) { cout << JN.ans + 1 << endl; bFlag = true; break; } for(int i = 0; i < 4; i++) { Pos Next = JN; Next.ans++; Next.x += dx[i]; Next.y += dy[i]; if(Next.x >= 1 && Next.x <= R && Next.y >= 1 && Next.y <= C && !pMap[Next.x][Next.y] && !pVF[Next.x][Next.y] && !pVJ[Next.x][Next.y]) { J.push(Next); pVJ[Next.x][Next.y] = true; } } } if(bFlag) { break; } nTime++; } if(!bFlag) { cout << "IMPOSSIBLE" << endl; } } return 0; }
POJ 3984
bfs水题。
#include <iostream> #include <memory.h> #include <queue> using namespace std; const int MAX = 8; const int dx[] = { 1, -1, 0, 0 }; const int dy[] = { 0, 0, 1, -1 }; struct Pos { Pos(int _x = 0, int _y = 0) { x = _x; y = _y; } int x, y; }; struct State { State(int _x = 0, int _y = 0) { Now = Pos(_x, _y); while(!Ans.empty()) { Ans.pop(); } } Pos Now; queue<Pos> Ans; }; int pMap[MAX][MAX]; bool pVisited[MAX][MAX]; queue<State> Q; int main() { for(int i = 1; i <= 5; i++) { for(int j = 1; j <= 5; j++) { cin >> pMap[i][j]; } } while(!Q.empty()) { Q.pop(); } memset(pVisited, false, sizeof(pVisited)); Q.push(State(1, 1)); pVisited[1][1] = true; while(!Q.empty()) { State Now = Q.front(); Q.pop(); if(Now.Now.x == 5 && Now.Now.y == 5) { while(!Now.Ans.empty()) { Pos Cur = Now.Ans.front(); cout << "(" << Cur.x - 1 << ", " << Cur.y - 1 << ")" << endl; Now.Ans.pop(); } cout << "(4, 4)" << endl; break; } for(int i = 0; i < 4; i++) { int nx = Now.Now.x + dx[i]; int ny = Now.Now.y + dy[i]; if(nx >= 1 && nx <= 5 && ny >= 1 && ny <= 5 && !pVisited[nx][ny] && !pMap[nx][ny]) { State Next = Now; Next.Now = Pos(nx, ny); Next.Ans.push(Now.Now); Q.push(Next); pVisited[nx][ny] = true; } } } return 0; }
HDU 1241
求连通块个数,直接dfs即可。
#include <iostream> #include <memory.h> #include <string> #include <queue> using namespace std; const int MAX = 128; const int dx[] = { -1, 0, 1, -1, 1, -1, 0, 1 }; const int dy[] = { 1, 1, 1, 0, 0, -1, -1, -1 }; int N, M; int pMap[MAX][MAX]; bool pVisited[MAX][MAX]; void dfs(int x, int y); int main() { string strTmp; while(cin >> N >> M) { if(N == 0 && M == 0) { break; } for(int i = 1; i <= N; i++) { cin >> strTmp; for(int j = 1; j <= M; j++) { if(strTmp[j - 1] == '*') { pMap[i][j] = 1; } else { pMap[i][j] = 0; } } } int ans = 0; memset(pVisited, false, sizeof(pVisited)); for(int i = 1; i <= N; i++) { for(int j = 1; j <= M; j++) { if(!pMap[i][j] && !pVisited[i][j]) { dfs(i, j); ans++; } } } cout << ans << endl; } return 0; } void dfs(int x, int y) { pVisited[x][y] = true; for(int i = 0; i < 8; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if(nx >= 1 && nx <= N && ny >= 1 && ny <= M && !pMap[nx][ny] && !pVisited[nx][ny]) { dfs(nx, ny); } } }
HDU 1495
这道题目和POJ 3414非常的类似,但相较来说更简单,也是一道bfs水题。
#include <iostream> #include <memory.h> #include <queue> using namespace std; const int MAX = 128; struct Cola { Cola(int _S = 0, int _N = 0, int _M = 0, int _ans = 0) { S = _S; N = _N; M = _M; ans = _ans; } int S, N, M, ans; }; int S, N, M; bool pVisited[MAX][MAX][MAX]; queue<Cola> Q; Cola Opt(Cola Now, int k); bool Check(Cola Now); int main() { while(cin >> S >> N >> M) { if(S == 0 && N == 0 && M == 0) { break; } if(S & 1) { cout << "NO" << endl; } else { bool bFlag = false; memset(pVisited, false, sizeof(pVisited)); while(!Q.empty()) { Q.pop(); } // 队列忘记清空 Q.push(Cola(S, 0, 0, 0)); pVisited[S][0][0] = true; while(!Q.empty()) { Cola Now = Q.front(); Q.pop(); if(Check(Now)) { cout << Now.ans << endl; bFlag = true; break; } for(int i = 0; i < 6; i++) { Cola Next = Opt(Now, i); if(!pVisited[Next.S][Next.N][Next.M]) { Q.push(Cola(Next.S, Next.N, Next.M, Next.ans)); pVisited[Next.S][Next.N][Next.M] = true; } } } if(!bFlag) { cout << "NO" << endl; } } } return 0; } Cola Opt(Cola Now, int k) { if(k == 0) { Now.N += Now.S; if(Now.N > N) { Now.S = Now.N - N; Now.N = N; } else { Now.S = 0; } } if(k == 1) { Now.S += Now.N; Now.N = 0; } if(k == 2) { Now.M += Now.S; if(Now.M > M) { Now.S = Now.M - M; Now.M = M; } else { Now.S = 0; } } if(k == 3) { Now.S += Now.M; Now.M = 0; } if(k == 4) { Now.N += Now.M; if(Now.N > N) { Now.M = Now.N - N; Now.N = N; } else { Now.M = 0; } } if(k == 5) { Now.M += Now.N; if(Now.M > M) { Now.N = Now.M - M; Now.M = M; } else { Now.N = 0; } } Now.ans++; return Now; } bool Check(Cola Now) { int x = Now.S, y = Now.N, z = Now.M, p = S / 2; return (x == p && y == p) || (x == p && z == p) || (y == p && z == p); }
HDU 2612
首先计算Y和M走到地图上每个点的最小时间,然后枚举每个点,计算Y和M走到该点时间和的最小值,最后结果乘以11分钟即可。
#include <iostream> #include <memory.h> #include <string> #include <queue> using namespace std; const int MAX = 256; const int dx[] = { 1, -1, 0, 0 }; const int dy[] = { 0, 0, 1, -1 }; struct Pos { Pos(int _x = 0, int _y = 0, int _s = 0) { x = _x; y = _y; s = _s; } int x, y, s; }; Pos SY, SM; int N, M; int pMap[MAX][MAX]; int pAns[2][MAX][MAX]; bool pVisited[MAX][MAX]; queue<Pos> Q; void Solve(Pos S, int k); int main() { string strTmp; while(cin >> N >> M) { memset(pAns, -1, sizeof(pAns)); for(int i = 1; i <= N; i++) { cin >> strTmp; for(int j = 1; j <= M; j++) { if(strTmp[j - 1] == '#') { pMap[i][j] = 1; } else if(strTmp[j - 1] == '@') { pMap[i][j] = 2; } else { pMap[i][j] = 0; } if(strTmp[j - 1] == 'Y') { SY = Pos(i, j, 0); } if(strTmp[j - 1] == 'M') { SM = Pos(i, j, 0); } } } Solve(SY, 0); Solve(SM, 1); int ans = 2147483647; for(int i = 1; i <= N; i++) { for(int j = 1; j <= M; j++) { if(pMap[i][j] == 2 && pAns[0][i][j] != -1 && pAns[1][i][j] != -1) { ans = min(ans, pAns[0][i][j] + pAns[1][i][j]); } } } cout << ans * 11 << endl; } return 0; } void Solve(Pos S, int k) { while(!Q.empty()) { Q.pop(); } memset(pVisited, false, sizeof(pVisited)); Q.push(S); pVisited[S.x][S.y] = true; while(!Q.empty()) { Pos Now = Q.front(); Q.pop(); if(pAns[k][Now.x][Now.y] == -1) { pAns[k][Now.x][Now.y] = Now.s; } for(int i = 0; i < 4; i++) { int nx = Now.x + dx[i]; int ny = Now.y + dy[i]; if(nx >= 1 && nx <= N && ny >= 1 && ny <= M && !pVisited[nx][ny] && pMap[nx][ny] != 1) { Q.push(Pos(nx, ny, Now.s + 1)); pVisited[nx][ny] = true; } } } }
刷完这个专题,感觉对bfs的理解更加深入透彻了。