有没有办法到达最后一个盒子 - GRAPH

时间:2015-08-06 11:34:38

标签: c++ algorithm graph

有问题: 第一个男人' (谁首先开始)必须到达最后一个方框,以便第二个男人' 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

l无法保护对e的访问权限。

甚至更简单

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

2 个答案:

答案 0 :(得分:4)

首先要创建每次访问e的地图距离。

然后它是minmax(或alpha-beta):

  • 如果g一个地图距离中的当前位置小于l当前位置是相同的地图距离,则g获胜。
  • 如果l在所有地图距离中距离越来越小或相等,g就会失败。
  • 其他g必须使用其有效地图之一才能到达目标,l计数器及其地图(或展台)。

(注意:g没有理由站立,因为l可能会这样做,我们处于相同的位置。)

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

答案 1 :(得分:2)

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

(并注意代码中的冗余; BFS1和BFS 2几乎完全相同,可以合并为一个函数。)

编辑:OP已添加(链接)新信息:e无法输入e

如果不优雅,对此算法的校正是显而易见的。考虑g周围的房间;如果l之前有g可以访问的<sc:VisitorIdentification runat="server" /> ,则@Html.Sitecore().VisitorIdentification() 获胜。

链接问题陈述中可能还有其他捕获; OP可以在问题本身中说明他想要回答的问题。我们不喜欢&#34;仅链接&#34;这里有问题。