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

洛谷 P2324 [SCOI2005] 骑士精神-提高+/省选-

题目描述

输入格式

第一行有一个正整数 TTTT≤10T \le 10T10),表示一共有 TTT 组数据。

接下来有 TTT5×55 \times 55×5 的矩阵,0 表示白色骑士,1 表示黑色骑士,* 表示空位。两组数据之间没有空行。

输出格式

对于每组数据都输出一行。如果能在 151515 步以内(包括 151515 步)到达目标状态,则输出步数,否则输出 -1

输入输出样例 #1

输入 #1

2
10110
01*11
10111
01001
00000
01011
110*1
01110
01010
00100

输出 #1

7
-1

说明/提示

solution

  • 1 状态压缩
    用低 5 位(0-4)表示空格的位置 (0 - 24)即 (00000->11000)
    用 5 - 29 位表示马的颜色 0 白 1 黑 (空格不管它,默认为0)
  • 2 状态切换
    找到空格的位置,切换空格和其中一个马(坐标相差为 1, 2的位置)的位置,修改空格坐标
  • 3 双向搜索各 8 步

代码

#include "cstring"
#include "string"
#include "algorithm"
#include "iostream"
#include "vector"
#include "unordered_set"
#include "unordered_map"using namespace std;int src, dest, offset;
unordered_set<int> set, set2;
bool first;/** 1 状态压缩*      用低 5 位(0-4)表示空格的位置 (0 - 24)即 (00000->11000)*      用 5 - 29 位表示马的颜色 0 白 1 黑 (空格不管它,默认为0)* 2 状态切换*      找到空格的位置,切换空格和其中一个马(坐标相差为 1, 2的位置)的位置,修改空格坐标* 3 双向搜索各 8 步**/void print(int x) {int pos = x & 31;for (int j = 0; j < 25; j++) {if (j % 5 == 0) cout << '\n';if (j == pos) {cout << '*';continue;}cout << ((x >> (j + 5)) & 1);}
}bool ok(int v) {if (first) return v == dest;return set.count(v);
}void check(vector<int> &q, int v) {if (first) {if (!set.count(v)) {set.insert(v);q.push_back(v);}} else {if (!set2.count(v)) {set2.insert(v);q.push_back(v);}}
}bool search() {vector<int> q[2];q[0].push_back(src);for (int i = 0; i < 8; i++) {for (int u: q[i & 1]) {int pos = u & 31;for (int j = 0; j < 25; j++) {if (j == pos) continue;int r = j / 5, c = j % 5, rr = pos / 5, cc = pos % 5;if (abs((r - rr) * (c - cc)) != 2) continue;// 将第 j 匹马移动到 pos 上int bit_j = (u >> (j + 5)) & 1; // j-th 马的颜色int v = u | (bit_j << (pos + 5)); // 移动到 pos 的地方// 修改 posv = v & ~31 | j;v &= ~(1 << (j + 5)); //相应的位置 置0if (ok(v)) { // 目标int ans = i + 1 + offset;if(ans == 16) cout << -1 << endl;else cout << ans << endl;return true;}check(q[i + 1 & 1], v);}}q[i & 1].clear();}offset = 8;return false;
}int main() {int T;cin >> T;while (T--) {src = 0;for (int i = 0; i < 25; i++) {char c;cin >> c;if (c == '*') {src |= i;c = '0';}src |= (c - '0') << (i + 5);}// 11111 01111 00011 00001 00000dest = 0b000001000011000111101111101100;if (dest == src) {cout << 0 << endl;continue;}set.clear();set2.clear();first = true;offset = 0;bool flag = search();if (flag) continue;first = false;src = dest;if (!search())cout << -1 << endl;}return 0;
}

结果

在这里插入图片描述

http://www.dtcms.com/a/336632.html

相关文章:

  • CE桥接MuMu模拟器
  • 计算机网络 Session 劫持 原理和防御措施
  • IC验证 AHB-RAM 项目(一)——项目理解
  • 【leetcode】58. 最后一个单词的长度
  • Python大模型应用开发-核心技术与项目开发
  • 【165页PPT】基于IPD的研发项目管理(附下载方式)
  • vue路由懒加载
  • 数据链路层(1)
  • Linux操作系统软件编程——多线程
  • 基于飞算JavaAI实现高端算法性能优化:从理论到落地的性能跃迁实践
  • C++---迭代器删除元素避免索引混乱
  • 【Golang】:函数和包
  • 因果语义知识图谱如何革新文本预处理
  • os详解,从上面是‘os‘模块?到核心组成和常用函数
  • 智能合约里的 “拒绝服务“ 攻击:让你的合约变成 “死机的手机“
  • 什么是AI Agent(智能体)
  • nature子刊:MCNN基于电池故障诊断的模型约束的深度学习方法
  • [Oracle数据库] Oracle 多表查询
  • 网络常识-我的电脑啥时安装了证书
  • 生成模型实战 | InfoGAN详解与实现
  • java如何使用正则提取字符串中的内容
  • 谈谈对面向对象OOP的理解
  • 深入分析 Linux PCI Express 子系统
  • Highcharts 官方文档与 API 查询技巧解析
  • android aidl相关学习
  • 【昇腾】单张48G Atlas 300I Duo推理卡MindIE+WebUI方式跑14B大语言模型_20250817
  • 在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo
  • 母猪姿态转换行为识别:计算机视觉与行为识别模型调优指南
  • redis和cdn的相似性和区别
  • 编程算法实例-最小公倍数