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;
}
相关推荐
wearegogog12321 小时前
三电平SVPWM逆变器仿真指南
单片机·算法
笨笨饿1 天前
74_SysTick滴答定时器中断
c语言·开发语言·人工智能·单片机·嵌入式硬件·算法·学习方法
2501_921960851 天前
协同本体论 V4.2+:离散关系拓扑涌现连续时空几何的数值验证
数据结构·人工智能·重构
pkowner1 天前
若依分页问题及解决方法
java·前端·算法
呃呃本1 天前
算法题(栈)
算法
通信小呆呆1 天前
基于 ADMM-MFOCUSS 的捷变频雷达扩展目标稀疏重构原理
算法·重构·信息与通信·信号处理·雷达
橙淮1 天前
Java数组与链表:特性对比与应用场景
数据结构·算法
炽烈小老头1 天前
【每天学习一点算法 2026/05/15】被围绕的区域
学习·算法·深度优先
芜湖xin1 天前
【题解-洛谷】P1012 [NOIP 1998 提高组] 拼数
算法·贪心
xiaoxiaoxiaolll1 天前
金属结构疲劳寿命预测与健康监测技术
人工智能·算法·机器学习