UVA-10384 推门游戏 题解答案代码 算法竞赛入门经典第二版

GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版

由于在迷宫中可以走的路线非常长,而且要求最短路线,因此这里使用了迭代加深搜索方式。

题目不难,每次行进的过程中注意墙和边缘的处理,然后走出迷宫的时候就表示得到结果了。

注意有推墙机制的存在,因此一个墙移动,有三个结点的数字会跟着移动:

  1. 当前位置减去当前墙

  2. 当前位置向前一个位置减去当前墙,增加前面的墙。

  3. 当前位置的前两个位置增加墙。

对应状态恢复的时候也要对这几个状态都恢复。

AC代码

cpp 复制代码
#include <stdio.h>
#include <string.h>

int arrWall[8][8];
int Steps[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
char StepConvert[4] = {'W', 'N', 'E', 'S'};
char StepRe[4] = {2, 3, 0, 1};
int stepArr[100000];

int stepMax;

bool outXY(int x, int y)
{
    if (x < 0 || x >= 4 || y < 0 || y >= 6)
        return true;
    return false;
}

void setWall(int x, int y, int i, bool set)
{
    int newX = x + Steps[i][0];
    int newY = y + Steps[i][1];
    int newnewX = newX + Steps[i][0];
    int newnewY = newY + Steps[i][1];
    int k = 1 << i;
    int rei = StepRe[i];
    int rek = 1 << rei;
    if (set)
    {
        arrWall[newX][newY] -= rek;
        arrWall[newX][newY] += k;
        arrWall[x][y] -= k;
        if (!outXY(newnewX, newnewY))
            arrWall[newnewX][newnewY] += rek;
        return;
    }
    arrWall[newX][newY] += rek;
    arrWall[newX][newY] -= k;
    arrWall[x][y] += k;
    if (!outXY(newnewX, newnewY))
        arrWall[newnewX][newnewY] -= rek;
}

bool computed(int x, int y, int stepNum)
{
    if (outXY(x, y))
        return true;
    if (stepNum >= stepMax)
        return false;
    int i, j, k, newX, newY;
    bool hasWall;
    for (i = 0; i < 4; ++i)
    {
        k = 1 << i;
        newX = x + Steps[i][0];
        newY = y + Steps[i][1];
        hasWall = false;
        // 有墙
        if (arrWall[x][y] & k)
        {
            hasWall = true;
            // 到边缘
            if (outXY(newX, newY))
                continue;
            // 再隔一层也有墙
            if (arrWall[newX][newY] & k)
                continue;
            setWall(x, y, i, true);
        }
        stepArr[stepNum] = i;
        if (computed(newX, newY, stepNum + 1))
            return true;
        // 回退墙
        if (hasWall)
            setWall(x, y, i, false);
    }
    return false;
}

int main()
{
    int x, y, t;
    int i, j, k;
    while (scanf("%d %d", &x, &y) == 2 && x != 0 && y != 0)
    {
        t = x;
        x = y;
        y = t;
        x = x - 1;
        y = y - 1;
        memset(arrWall, 0, sizeof(arrWall));
        for (i = 0; i < 4; ++i)
        {
            for (j = 0; j < 6; ++j)
                scanf("%d", &arrWall[i][j]);
        }
        for (i = 0;; ++i)
        {
            stepMax = i;
            if (computed(x, y, 0))
                break;
        }
        for (j = 0; j < i; ++j)
            putchar(StepConvert[stepArr[j]]);
        putchar('\n');
    }
    return 0;
}
相关推荐
To_OC10 小时前
LC 128 最长连续序列:别上来就排序,O (n) 解法才是这题的灵魂
javascript·算法·leetcode
刘马想放假1 天前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
05Kevin1 天前
lk每日冒险题--数据结构6.27
算法
To_OC1 天前
从一次栈溢出报错说起,我把递归彻底扒明白了
javascript·算法·程序员
千纸鹤安安2 天前
千问Qwen-AgentWorld来了:一个语言模型搞定七大Agent场景,GPT-5.4都输了
算法
七牛开发者2 天前
MCP 到底是什么?为什么 Agent 都想接上它
算法·aigc·agent
北域码匠2 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法