UVA1601万圣节的早上
作者:互联网
此题非常经典,确实学习到了很多的东西;
路径搜索这种类型的题目步骤是这样的:
第一保存状态
第二寻找状态之间的关系,即一个状态能够走向哪些状态
第三判断这个新产生的状态是否已经走过。
scanf("%d%d%d\n");后面加\N,下次读的时候就可以换行读,和fgets配合起来很好用
如果开数组可以把所有的状态都包含进来的话,那么就可以去开数组
学到的东西,只需要保存各个可以走的cell就可以了
这道题目还需要以后再细细品味一下
下面是AC代码:
#include<cstdio> #include<vector> #include<queue> #include<cstring> using namespace std; const int maxn = 150;//状态个数的估计是非常重要的 struct state { int fir,sec,thir; state(int a = 0,int b = 0,int c = 0):fir(a),sec(b),thir(c){} }; int dist[maxn][maxn][maxn]; int start[3]; int End[3]; char G[20][20]; vector<int>Next[150]; int cnt = 0; int dr[] = {-1,0,1,0}; int dc[] = {0,1,0,-1}; bool read_input() { cnt = 0; memset(dist,0,sizeof(dist)); //start.clear(); //End.clear(); for(int i = 0;i < 150;i++) { Next[i].clear(); } int row,col,num_ghost; scanf("%d%d%d\n",&col,&row,&num_ghost); if(!row) { return false; } //cnt代表此时用多少个可以走的cell for(int i = 0;i < row;i++) { fgets(G[i],20,stdin); for(int j = 0;j < col;j++) { if(G[i][j] != '#') { if(G[i][j] <= 'Z' && G[i][j] >= 'A') { End[G[i][j] - 'A'] = cnt; //End.push_back(cnt); } else if(G[i][j] <= 'z' && G[i][j] >= 'a') { start[G[i][j] - 'a'] = cnt; } G[i][j] = cnt; cnt++; } } } for(int r = 0;r < row;r++) { for(int c = 0;c < col;c++) { if(G[r][c] != '#') { Next[G[r][c]].push_back(G[r][c]); for(int k = 0;k < 4;k++) { if(G[r + dr[k]][c + dc[k]] != '#') { Next[G[r][c]].push_back(G[r + dr[k]][c + dc[k]]); } } } } } if(num_ghost == 1) { Next[cnt + 1].push_back(cnt + 1); Next[cnt + 2].push_back(cnt + 2); start[1] = cnt + 1; start[2] = cnt + 2; End[1] = cnt + 1; End[2] = cnt + 2; //start.push_back(cnt + 1); //start.push_back(cnt + 2); } else if(num_ghost == 2) { Next[cnt + 1].push_back(cnt + 1); start[2] = cnt + 1; End[2] = cnt + 1; //start.push_back(cnt + 1); } return 1; } void BFS() { memset(dist,-1,sizeof(dist)); queue<state>Q; state u(start[0],start[1],start[2]); Q.push(u); dist[start[0]][start[1]][start[2]] = 0; while(!Q.empty()) { state u = Q.front(); Q.pop(); if(u.fir == End[0] && u.sec ==End[1] && u.thir == End[2]) { printf("%d\n",dist[End[0]][End[1]][End[2]]); return ;//找到了答案 } int fir1 ,sec1,thir1; for(int i = 0;i < Next[u.fir].size();i++) { fir1 = Next[u.fir][i]; for(int j = 0; j < Next[u.sec].size();j++) { sec1 = Next[u.sec][j]; if(fir1 == sec1 || (u.fir == sec1 && u.sec == fir1)) continue; for(int k = 0;k < Next[u.thir].size();k++) { thir1 = Next[u.thir][k]; if(fir1 == thir1 || (u.fir == thir1 && u.thir == fir1)) continue; if(sec1 == thir1 || (u.thir == sec1 && u.sec == thir1)) continue; state v(fir1,sec1,thir1); if(dist[fir1][sec1][thir1] < 0 ) { dist[fir1][sec1][thir1] = dist[u.fir][u.sec][u.thir] + 1; Q.push(v); } } } } } } int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); while(read_input()) { BFS(); } return 0; }
标签:cnt,万圣节,End,UVA1601,int,Next,start,早上,push 来源: https://www.cnblogs.com/TorettoRui/p/10495611.html