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;
    }
}

 

posted @ 2021-11-10 22:37  重言  阅读(33)  评论(0)    收藏  举报