有没有办法到达最后一个方框——GRAPH

Is there the way to reach the final box - GRAPH

本文关键字:方框 GRAPH 最后一个 有没有      更新时间:2023-10-16

存在问题:第一个人"g"(先发(必须到达最后一个箱子"e",这样第二个人"l"(无论何时(都无法赶上第一个人。这些人可以向左、向右、向上、向下,也可以留下来。

例如:

Input:
6 7
RRRRRRR
R_e___R
R_____R
R_RRR_R
R_gRl_R
RRRRRRR

答案是"是",因为有路(左、上、上、下、右(。

如何解决这个问题?

我正在使用BFS和DFS。这是我的代码

#include <iostream>
#include <algorithm>
#include <stack>
#include <math.h>
#include <cstring>
#include <map>
#include <queue>
using namespace std;
const int MAX = 32;
char a[MAX][MAX];
int used[MAX][MAX], m1[MAX][MAX], m2[MAX][MAX];;
int movesx[8] = {-1, 1, 0, 0};
int movesy[8] = { 0, 0, -1, 1};
int n, m, c = 0, flag = 0;
struct pc {
    int x, y;
};
pc li, ga, fi;
queue <pc> q;
void BFS1(pc v) {
    pc from, to;
    memset(m1,0,sizeof(m1)); m1[v.y][v.x] = 0;
    memset(used, 0, sizeof(used));
    q.push(v); used[v.y][v.x] = 1;
    while(!q.empty())
    {
        from = q.front(); q.pop();
        for(int i = 0; i < 4; ++i) {
            int x = from.x + movesy[i], y = from.y + movesx[i];
            if( (a[y][x] == ' ' || a[y][x] == 'g' ) && !used[y][x]) {
                used[y][x] = 1;
                m1[y][x] = m1[from.y][from.x] + 1;
                pc temp;
                temp.x = x;
                temp.y = y;
                q.push(temp);
            }
        }
    }
}
void BFS2(pc v) {
    pc from, to;
    memset(m2,0,sizeof(m2)); m2[v.y][v.x] = 0;
    memset(used, 0, sizeof(used));
    q.push(v); used[v.y][v.x] = 1;
    while(!q.empty())
    {
        from = q.front(); q.pop();
        for(int i = 0; i < 4; ++i) {
            int y = from.y + movesy[i], x = from.x + movesx[i];
            if( (a[y][x] == ' ' || a[y][x] == 'l' ) && !used[y][x]) {
                used[y][x] = 1;
                m2[y][x] = m2[from.y][from.x] + 1;
                pc temp;
                temp.x = x;
                temp.y = y;
                q.push(temp);
            }
        }
    }
}
void DFS(pc v) {
    used[v.y][v.x] = 1;
    for(int i = 0; i < 4; ++i) {
        int x = v.x + movesx[i], y = v.y + movesy[i];
        if(a[y][x] == 'e') {
                c = 1;
                flag = 1;
                return;
        }
        if( (a[y][x] == ' ' ) && !used[y][x] && m2[y][x] < m1[y][x] && flag == 0 ) {
            pc temp;
            temp.x = x;
            temp.y = y;
            DFS(temp);
        }
    }
}
int main() {
        c = 0, flag = 0;
        memset(used, 0, sizeof(used));
        memset(a, 'R', sizeof(a));
        cin >> n >> m;
        string s;
        getline(cin, s);
        for(int i = 0; i < n; ++i) {
            getline(cin, s);
            for(int j = 0; j < m; ++j) {
                a[i][j] = s[j];
                if(a[i][j] == 'g') {
                    ga.x = j;
                    ga.y = i;
                }
                else if(a[i][j] == 'l') {
                    li.x = j;
                    li.y = i;
                }
                else continue;
            }
        }
        BFS1(li);
        BFS2(ga);
        memset(used, 0, sizeof(used));
        DFS(ga);
        if(c == 1) {
            cout << "YES" << endl;
        }
        else {
            cout << "NO" << endl;
        }
}

这是第二个代码:

#include <iostream>
#include <algorithm>
#include <stack>
#include <math.h>
#include <cstring>
#include <map>
#include <queue>
using namespace std;
const int MAX = 32;
char a[MAX][MAX];
int used[MAX][MAX], m1[MAX][MAX], m2[MAX][MAX];;
int an[1002][MAX][MAX];
int movesx[8] = {-1, 1, 0, 0, 0};
int movesy[8] = { 0, 0, -1, 1, 0};
int n, m, c = 0, flag = 0;
struct pc {
    int x, y;
};
pc li, ga;
void functionD() {
    for(int z = 1; z <= 1000; ++z) {
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < n; ++j) {
                if(an[z - 1][i][j] == 1) {
                    int x, y;
                    for(int k = 0; k < 5; ++k) {
                        x = j + movesx[k];
                        y = i + movesy[k];

                        if(x < m && y < n && x >= 0 && y >= 0) {
                            if(a[y][x] != 'R' && a[y][x] != 'e') {
                                an[z][y][x] = 1;
                            }
                        }
                    }
                }
            }
        }
    }

}
void DFS(pc v, int k) {
    used[v.y][v.x] = 1;
    for(int i = 0; i < 5; ++i) {
        int x = v.x + movesx[i], y = v.y + movesy[i];
        if(a[y][x] == 'e') {
                c = 1;
                flag = 1;
                return;
        }
        if(an[k][y][x] == 0 && a[y][x] != 'R' && !used[y][x] && flag == 0 && k <= 1000) {
            pc temp;
            temp.x = x;
            temp.y = y;
            DFS(temp, k + 1);
        }
    }
}
int main() {
    int nn; cin >> nn;
    for(int z = 0; z < nn; ++z) {
        c = 0, flag = 0;
        memset(used, 0, sizeof(used));
        memset(a, 'R', sizeof(a));
        cin >> n >> m;
        string s;
        getline(cin, s);
        for(int i = 0; i < n; ++i) {
            getline(cin, s);
            for(int j = 0; j < m; ++j) {
                a[i][j] = s[j];
                if(a[i][j] == 'g') {
                    ga.x = j;
                    ga.y = i;
                }
                else if(a[i][j] == 'l') {
                    li.x = j;
                    li.y = i;
                }
            }
        }
        an[0][li.y][li.x] = 1;
        functionD();

        DFS(ga, 1);

        if(c == 1) {
            cout << "YES" << endl;
        }
        else {
            cout << "NO" << endl;
        }
    }
}

编辑(Jarod42(:

我发现了一个失败的棘手地图:

9 9
RRRRRRRRR
R...Rg..R
R.RlRRR.R
R.R...R.R
R.RRR.R.R
R.Re....R
R.R.RRR.R
R.......R
RRRRRRRRR

CCD_ 1不能同时保护对CCD_ 2的访问。

或者更简单的

RRRRRRRRRR
R...RRRRRR
R.R...RRRR
RlReR...gR
R.R...RRRR
R...RRRRRR
RRRRRRRRRR

您必须首先创建每次访问e的映射距离。

然后是一个最小最大值(或α-β(:

  • g当前位置在一个地图距离内小于l当前位置在相同地图距离内,则g获胜
  • 如果l在所有映射距离中具有更小或相等的距离,则g丢失
  • 否则g必须使用其有效地图中的一个才能达到目标,l0用其地图(或看台(进行计数

(注:g没有理由站出来,因为l可能也会这样做,我们也在同一点上(。

(编辑:注意:在提供的链接中,似乎必须静态选择安全路径,因此动态部分(第三个项目符号(对于g来说是松散的(

不需要DFS。只需测试l是否能在g之前达到e即可。如果可以的话,他可以抓住g,否则g获胜。

(注意代码中的冗余;BFS1和BFS2几乎完全相同,可以组合成一个函数。(

编辑:OP已添加(链接到(新信息:l无法进入e0。

对这个算法的修正是显而易见的,虽然不雅。考虑e周围的房间;如果在l之前有一个g可以到达,则g获胜。

在关联的问题陈述中可能还有其他陷阱;OP可以在问题本身中陈述他想要回答的问题。我们不喜欢这里的"仅链接"问题。