UVa 10384 The Wall Pusher IDA* itération plus A*

Lien de la question : Description du titre de Wall Pusher
 :

Étant donné une grille et l'emplacement de départ de la tâche, votre tâche est de trouver un chemin pour sortir de la grille. Il peut y avoir des murs autour de la grille. S'il y a des murs autour et qu'il n'y a qu'un seul mur continu dans cette direction, vous peut pousser le Si vous bloquez un mur, le mur se déplacera sur une distance dans la direction, mais s'il y a deux ou plusieurs murs consécutifs dans la direction, il ne peut pas se déplacer dans la direction (vous ne pouvez pas supprimer le mur de bord de la grille). Il est garanti qu'il existe un ensemble de solutions pour l'entrée et que tout ensemble de solutions est généré en sortie.
Solution :
Cette question peut utiliser IDA ∗ IDA*I D A A ∗ A*A peut utiliser la distance de Manhattan comme fonction d'évaluation, et le processus de recherche n'est pas difficile.

Code:

#include <bits/stdc++.h>

const int ROW_NUM = 4;
const int COLUMN_NUM = 6;
const int DIRECTION_NUM = 4;
const int INF = 0x3f3f3f3f;

using namespace std;

int n, m, x, y, maxDepth;
int grid[ROW_NUM][COLUMN_NUM];
int dx[] = {
    
    1, -1, 0, 0};
int dy[] = {
    
    0, 0, 1, -1};
char direction[] = "SNEW";
int directionNum[] = {
    
    8, 2, 4, 1};
string ans;
vector<pair<int, int>> destination;

enum ENUM_DIRECTION
{
    
    
    SOUTH,
    NORTH,
    EAST,
    WEST,
};

bool inBound(int x, int y)
{
    
    
    return x >= 0 && x < ROW_NUM && y >= 0 && y < COLUMN_NUM;
}

int minDis(int x, int y)
{
    
    
    int res = INF;
    for (auto ed : destination) {
    
    
        res = min(res, abs(ed.first - x) + abs(ed.second - y) + 1);
    }
    return res;
}

bool dfs(int nowDepth, int x, int y)
{
    
    
    if (nowDepth == maxDepth) {
    
     return !inBound(x, y); }
    if (nowDepth + minDis(x, y) > maxDepth) {
    
     return false; }
    for (int i = 0; i < DIRECTION_NUM; i++) {
    
    
        int nx = x + dx[i];
        int ny = y + dy[i];
        if ((grid[x][y]&directionNum[i]) == 0) {
    
     // 没有墙
            ans.push_back(direction[i]);
            if (dfs(nowDepth + 1, nx, ny)) {
    
     return true; }
            ans.pop_back();
        } else if (inBound(nx, ny) && (grid[nx][ny] & directionNum[i]) == 0){
    
     // 该方向上只有一个墙
            int nnx = nx + dx[i];
            int nny = ny + dy[i]; // 这里还需要考虑该方向后一个的反方向也会增加一面墙
            grid[x][y] ^= directionNum[i];
            grid[nx][ny] ^= directionNum[i];
            if (inBound(nnx, nny)) {
    
     grid[nnx][nny] ^= directionNum[i ^ 1]; }
            ans.push_back(direction[i]);
            if (dfs(nowDepth + 1, nx, ny)) {
    
     return true; }
            grid[x][y] ^= directionNum[i];
            grid[nx][ny] ^= directionNum[i];
            if (inBound(nnx, nny)) {
    
     grid[nnx][nny] ^= directionNum[i ^ 1]; }
            ans.pop_back();
        }
    }
    return false;
}

int main()
{
    
    
    while (cin >> x >> y && x != 0 && y != 0) {
    
    
        ans = "";
        destination.resize(0);
        swap(x, y);
        x--, y--;
        for (int i = 0; i < ROW_NUM; i++) {
    
    
            for (int j = 0; j < COLUMN_NUM; j++) {
    
    
                cin >> grid[i][j];
                // 可能会有重复的点进入vector但是这对效率的影响很低
                if (i == 0 && (grid[i][j] & directionNum[NORTH]) == 0) {
    
     destination.push_back({
    
    i, j}); }
                if (j == 0 && (grid[i][j] & directionNum[WEST]) == 0) {
    
     destination.push_back({
    
    i, j}); }
                if (i == ROW_NUM - 1 && (grid[i][j] & directionNum[SOUTH]) == 0) {
    
     destination.push_back({
    
    i, j}); }
                if (j == COLUMN_NUM - 1 && (grid[i][j] & directionNum[EAST]) == 0) {
    
     destination.push_back({
    
    i, j}); }
            }
        }
        for (maxDepth = 0; ; maxDepth++) {
    
    
            if (dfs(0, x, y)) {
    
    
                cout << ans << endl;
                break;
            }
        }
    }
    return 0;
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_45523675/article/details/129453927
conseillé
Classement