当前位置: 首页 > article >正文

【拉箱子——模拟+DFS】

题目

代码

#include <bits/stdc++.h>
using namespace std;
map<vector<vector<int>>, int> check;
vector<vector<int>> mp;
int n, m, ans;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
void dfs(vector<vector<int>> tmp, int ax, int ay, int bx, int by, int cx, int cy)
{
    if (ax == bx && ay == by) // 处理人箱重叠的情况(这里不能推箱子)
    {
        for (int k = 0; k < 4; k++) // 人移动
        {
            int tx = ax + dx[k];
            int ty = ay + dy[k];
            if (tx < 0 || ty < 0 || tx >= n || ty >= m || tmp[tx][ty] == 1) // 边界和墙判断
                continue;
            tmp[ax][ay] -= 1 << 1, tmp[tx][ty] += 1 << 1;
            dfs(tmp, tx, ty, bx, by, cx, cy);
            tmp[ax][ay] += 1 << 1, tmp[tx][ty] -= 1 << 1;
        }
        return;
    }

    if (check.count(tmp))
        return; // 判断状态是否考虑过
    if (!(bx == cx && by == cy) && !(ax == cx && ay == cy))
        ans++; // 没考虑过且符合要求(放在这里是要借助前面的人箱不重叠条件,但是实测放在最前也可以)
    check[tmp] = 1;

    for (int k = 0; k < 4; k++) // 到这里,就说明出现人终重叠或者是箱终重叠,考虑人移动和推箱子来解决
    {
        int tx = ax + dx[k]; // 人移动
        int ty = ay + dy[k];
        if (tx < 0 || ty < 0 || tx >= n || ty >= m || tmp[tx][ty] == 1)
            continue;
        if (tx != bx || ty != by) // 人没移动到箱子上
        {
            tmp[ax][ay] -= 1 << 1, tmp[tx][ty] += 1 << 1;
            dfs(tmp, tx, ty, bx, by, cx, cy);
            tmp[ax][ay] += 1 << 1, tmp[tx][ty] -= 1 << 1;
        }
        int ttx = bx + dx[k];
        int tty = by + dy[k];
        if (tx == bx && ty == by && ttx >= 0 && ttx < n && tty >= 0 && tty < m && tmp[ttx][tty] != 1)
        { // 人移动的目的地是箱子的起始地
            tmp[ax][ay] -= 1 << 1, tmp[tx][ty] += 1 << 1;
            tmp[bx][by] -= 1 << 2, tmp[ttx][tty] += 1 << 2;
            dfs(tmp, tx, ty, ttx, tty, cx, cy);
            tmp[ax][ay] += 1 << 1, tmp[tx][ty] -= 1 << 1;
            tmp[bx][by] += 1 << 2, tmp[ttx][tty] -= 1 << 2;
        }
    }
}
int main()
{
    cin >> n >> m;
    mp = vector<vector<int>>(n, vector<int>(m));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cin >> mp[i][j];
        }
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (mp[i][j] == 0)
            {
                mp[i][j] = (1 << 1) + (1 << 2) + (1 << 3);
                dfs(mp, i, j, i, j, i, j);
                mp[i][j] = 0;
            }
        }
    }
    cout << ans << '\n';
    return 0;
}


http://www.kler.cn/a/395719.html

相关文章:

  • 【eNSP】路由基础与路由来源——静态路由实验
  • 华为机试HJ41 称砝码
  • A3超级计算机虚拟机,为大型语言模型LLM和AIGC提供强大算力支持
  • vue3+elementplus+虚拟树el-tree-v2+多条件筛选过滤filter-method
  • Docker compose部署portainer
  • Windows C++ TCP/IP 两台电脑上互相传输字符串数据
  • JAVA学习-练习试用Java实现“网络编程”
  • LlamaFactory介绍
  • Java爬虫:获取商品历史价格信息 API 数据
  • 英伟达基于Mistral 7B开发新一代Embedding模型——NV-Embed-v2
  • CTF攻防世界小白刷题自学笔记12
  • 企业生产环境-麒麟V10(ARM架构)操作系统部署kafka高可用集群
  • Lambda常用方法
  • Kafka、RabbitMQ、RocketMQ对比
  • 开源对象存储新选择:在Docker上部署MinIO并实现远程管理
  • sql在按照当前表查询返回
  • 聊天服务器(9)一对一聊天功能
  • 求10000以内n的阶乘
  • SpringBoot开发——整合AJ-Captcha实现安全高效的滑动验证码
  • day-82 最少翻转次数使二进制矩阵回文 I
  • SQL LEFT JOIN 简介
  • windbg的线程信息dt命令
  • 前端项目一键打包自动部署2.0版本
  • Linux故障排查中常用的命令
  • idea 实现版本的切换
  • Java 使用MyBatis-Plus数据操作关键字冲突报错You have an error in your SQL syntax问题