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;
}
相关推荐
Jasmine_llq19 小时前
《P13016 [GESP202506 六级] 最大因数》
数据结构·算法
白狐_79819 小时前
考研408算法设计题保命策略:链表专题暴力解法精讲(2015 & 2019真题实战)
考研·算法·链表
fangpin19 小时前
GPU编程2: 并行策略
算法
碧海银沙音频科技研究院20 小时前
8基于BES2700IHC数字助听器系统开发
嵌入式硬件·算法
HZZD_HZZD20 小时前
智能电表选CoAP还是MQTT?合众致达万表实测:CoAP省流17.3%、续航提升38%,附报文拆解与选型矩阵
算法
linux-hzh20 小时前
百日算法修炼 · Day 05
java·算法
paopaokaka_luck20 小时前
基于springboot3+vue3的云南本土影视文旅推荐平台(协同过滤算法、Echarts图形化分析)
前端·spring boot·学习·算法·echarts·mybatis
Ivanqhz21 小时前
泰勒展开(Taylor Expansion)
算法·决策树·机器学习·集成学习
凉茶钱21 小时前
【数据结构】C语言实现队列
c语言·数据结构
zander2581 天前
34. 在排序数组中查找元素的第一个和最后一个位置:用两个边界定位区间
数据结构·算法·leetcode