CCF201312-5 I’m stuck!
思路:
就是首先从S点出发,在DFS的过程中记录路径。如果路径路过了T,那么把路径上的点标作”可以到达目的地“。然后从每一个S可达但是在遍历的时候它不可以到达目的地的点开始DFS,如果它到了一个”可以到达目的地“的点,那么就把它路径上的点全部标作”可以到达目的地“。
反思:
首先这道题看题目理解题意不准,在写完了才发现题意理解错了,非常不应该。
其次在每次遍历的时候为了防止回头,应该重置visited数组,这里也没有重置。
代码:
#include <iostream> #include <vector> #include <algorithm> #include <cstdio> using namespace std; char mymap[51][51]; bool visited[51][51]; bool canreach[51][51]; bool visited2[51][51]; bool hasreached = false; typedef struct{ int i; int j; }pos; int r,c; pos src; pos des; template class std::vector<pos>; vector<pos> path; vector<pos> path2; bool cango(int x, int y){ if(visited[x][y]){ return false; } if(mymap[x][y] == '#'){ return false; } if(x < 0 || x >= r || y < 0 || y >= c){ return false; } return true; } bool cango2(int x, int y){ if(visited2[x][y]){ return false; } if(!visited[x][y]){ return false; } if(mymap[x][y] == '#'){ return false; } if(x < 0 || x >= r || y < 0 || y >= c){ return false; } return true; } void dfs(int x, int y){ visited[x][y] = true; if(mymap[x][y] == '.'){ if(cango(x + 1, y)){ pos tmp = {x + 1, y}; path.push_back(tmp); dfs(x + 1, y); path.pop_back(); } }else if(mymap[x][y] == '+'){ int disx[] = {1, 0, 0, -1}; int disy[] = {0, 1, -1, 0}; for(int i = 0;i<4;i++){ if(cango(x + disx[i], y + disy[i])){ pos tmp = {x + disx[i], y + disy[i]}; path.push_back(tmp); dfs(x + disx[i], y + disy[i]); path.pop_back(); } } }else if(mymap[x][y] == '|'){ int disx[] = {1, -1}; int disy[] = {0, 0}; for(int i = 0;i<2;i++){ if(cango(x + disx[i], y + disy[i])){ pos tmp = {x + disx[i], y + disy[i]}; path.push_back(tmp); dfs(x + disx[i], y + disy[i]); path.pop_back(); } } }else if(mymap[x][y] == '-'){ int disx[] = {0, 0}; int disy[] = {1, -1}; for(int i = 0;i<2;i++){ if(cango(x + disx[i], y + disy[i])){ pos tmp = {x + disx[i], y + disy[i]}; int len_before = path.size(); path.push_back(tmp); dfs(x + disx[i], y + disy[i]); path.pop_back(); int len = path.size(); } } }else if(mymap[x][y] == 'S'){ int disx[] = {1, 0, 0, -1}; int disy[] = {0, 1, -1, 0}; for(int i = 0;i<4;i++){ if(cango(x + disx[i], y + disy[i])){ pos tmp = {x + disx[i], y + disy[i]}; int len_before = path.size(); path.push_back(tmp); dfs(x + disx[i], y + disy[i]); path.pop_back(); int len = path.size(); } } }else if(mymap[x][y] == 'T'){ for(int i = 0;i<path.size();i++){ canreach[path[i].i][path[i].j] = true; } hasreached = true; int disx[] = {1, 0, 0, -1}; int disy[] = {0, 1, -1, 0}; for(int i = 0;i<4;i++){ if(cango(x + disx[i], y + disy[i])){ pos tmp = {x + disx[i], y + disy[i]}; int len_before = path.size(); path.push_back(tmp); dfs(x + disx[i], y + disy[i]); path.pop_back(); int len = path.size(); } } } } void dfs2(int x, int y){ visited2[x][y] = true; if(mymap[x][y] == '.'){ if(cango2(x + 1, y)){ if(canreach[x + 1][y]){ for(int i = 0;i<path2.size();i++){ canreach[path2[i].i][path2[i].j] = true; } }else{ pos tmp = {x + 1, y}; path2.push_back(tmp); dfs2(x + 1, y); path2.pop_back(); } } }else if(mymap[x][y] == '+'){ int disx[] = {1, 0, 0, -1}; int disy[] = {0, 1, -1, 0}; for(int i = 0;i<4;i++){ if(cango2(x + disx[i], y + disy[i])){ if(canreach[x + disx[i]][y + disy[i]]){ for(int k = 0;k<path2.size();k++){ canreach[path2[k].i][path2[k].j] = true; } }else{ pos tmp = {x + disx[i], y + disy[i]}; path2.push_back(tmp); dfs2(x + disx[i], y + disy[i]); path2.pop_back(); } } } }else if(mymap[x][y] == '|'){ int disx[] = {1, -1}; int disy[] = {0, 0}; for(int i = 0;i<2;i++){ if(cango2(x + disx[i], y + disy[i])){ if(canreach[x + disx[i]][y + disy[i]]){ for(int k = 0;k<path2.size();k++){ canreach[path2[k].i][path2[k].j] = true; } }else{ pos tmp = {x + disx[i], y + disy[i]}; path2.push_back(tmp); dfs2(x + disx[i], y + disy[i]); path2.pop_back(); } } } }else if(mymap[x][y] == '-'){ int disx[] = {0, 0}; int disy[] = {1, -1}; for(int i = 0;i<2;i++){ if(cango2(x + disx[i], y + disy[i])){ if(canreach[x + disx[i]][y + disy[i]]){ for(int k = 0;k<path2.size();k++){ canreach[path2[k].i][path2[k].j] = true; } }else{ pos tmp = {x + disx[i], y + disy[i]}; path2.push_back(tmp); dfs2(x + disx[i], y + disy[i]); path2.pop_back(); } } } }else if(mymap[x][y] == 'S'){ for(int i = 0;i<path2.size();i++){ canreach[path2[i].i][path2[i].j] = true; } }else if(mymap[x][y] == 'T'){ for(int i = 0;i<path2.size();i++){ canreach[path2[i].i][path2[i].j] = true; } } } void show(){ for(int i = 0;i<r;i++){ for(int j = 0;j<c;j++){ cout<<canreach[i][j]<<" "; } cout<<endl; } } int main(){ cin>>r>>c; getchar(); fill(visited[0], visited[0] + 51 * 51, false); fill(canreach[0], canreach[0] + 51 * 51, false); for(int i = 0;i<r;i++){ for(int j = 0;j<c;j++){ mymap[i][j] = getchar(); if(mymap[i][j] == 'S'){ src.i = i; src.j = j; } if(mymap[i][j] == 'T'){ des.i = i; des.j = j; } } char c = getchar(); } visited[src.i][src.j] = true; path.push_back(src); dfs(src.i, src.j); if(!hasreached){ cout<<"I'm stuck!"; }else{ for(int i = 0;i<r;i++){ for(int j = 0;j<c;j++){ if(visited[i][j] && !canreach[i][j]){ fill(visited2[0], visited2[0] + 51 * 51, false); pos tmp = {i, j}; path2.push_back(tmp); dfs2(i, j); path2.pop_back(); // show(); } } } int cnt = 0; for(int i = 0;i<r;i++){ for(int j = 0;j<c;j++){ if(visited[i][j] && !canreach[i][j]){ cnt++; } } } cout<<cnt; } }