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

UVa1063/LA3807 Marble Game

UVa1063/LA3807 Marble Game

  • 题目链接
  • 题意
    • 输入格式
    • 输出格式
  • 分析
  • AC 代码

题目链接

  本题是2007年icpc世界总决赛的F题

题意

  滚球游戏由一个 n×n(2≤n≤4)网格棋盘和 m 个小球组成。棋盘上恰好有 m 个单元格里有洞。球和洞均编号为 1~m。滚球游戏的目标为把每个球滚到编号相同的洞中。单元格的 4 条边上可能会有墙,可以阻挡球的滚动(见后)。
  每次可以把棋盘朝着上下左右 4 个方向之一微微抬起,然后所有球同时朝另一个方向滚动,直到碰到墙、洞或者另一个球。球在滚动的过程不能跳起(因而无法越过墙、其他球或者洞),也不能离开棋盘(整个棋盘的四周都有墙)。每个单元格恰好能容纳一个球。当球落入洞之后,洞将被填平,使得今后可以有其他球经过。入洞的球将无法出洞。
  下图所示是一个滚球游戏及其解法。你的任务是解决任意一个 n×n 棋盘上的滚球游戏,找出移动次数最小的解,输出其长度。
Marble Game

输入格式

  输入包含多组数据。每组数据第一行为 3 个整数 N、M、W(2≤N≤4,M>0)N、M、W\;(2 \le N \le 4,M>0)NMW(2N4,M>0),分别表示网格尺寸、球的数量(也是洞的数量)和墙的数量。接下来 MMM 行每行 2 个数字,依次代表每个球的行列编号。接下来 MMM 行每行 2 个数字,依次代表每个洞的行列编号。最后 WWW 行每行 4 个整数,分别表示墙两边格子的行列编号。输入结束标志为三个 0。

输出格式

  对于每组数据,如果有解则输出一行 Case k: ans moves,无解则输出一行 Case k: impossible,其中 k 为测试数据的编号(编号从 1 开始),ans 为最小移动次数。每组数据输出一行后还需要再输出一个空行。

分析

  本题直接广度优先搜索,模拟游戏过程直到找到解或者判定出无解即可。

AC 代码

#include <iostream>
#include <cstring>
using namespace std;#define M 50001
#define N 4
int a[N][N], e[N][N], f[N][N], h[N][N], q[M], m, n, w, c, kase = 0;
long long s[M], g[M]; bool l[N][N], r[N][N], t[N][N], b[N][N];bool term() {for (int i=0; i<n; ++i) for (int j=0; j<n; ++j) if (f[i][j]) return false;return true;
}void decode(long long x, long long y) {for (int i=n-1; i>=0; --i) for (int j=n-1; j>=0; --j) a[i][j] = x & 15, h[i][j] = y & 15, x >>= 4, y >>= 4;
}void insert() {long long x = 0, y = 0;for (int i=0; i<n; ++i) for (int j=0; j<n; ++j) x = x<<4 | e[i][j], y = y<<4 | f[i][j];int k = x % M;while (s[k]) {if (s[k] == x) return;++ k;}s[k] = x; g[k] = y; q[c++] = k;
}bool move_l() {for (int i=0; i<n; ++i) for (int j=0; j<n; ++j) e[i][j] = a[i][j], f[i][j] = h[i][j];for (int i=0; i<n; ++i) for (int j=n-2, k; j>=0; --j) if (f[i][j]) {for (k=j+1; !l[i][k] && !f[i][k]; ++k) if (e[i][k]) {if (e[i][k] != f[i][j]) return false;e[i][k] = f[i][j] = 0; break;}}for (int i=0; i<n; ++i) for (int j=0, k; j<n; ++j) if (!e[i][j]) {for (k=j; !r[i][k]; ++k) if (e[i][k]) break;if (k > j) e[i][j] = e[i][k], e[i][k] = 0;}return true;
}bool move_r() {for (int i=0; i<n; ++i) for (int j=0; j<n; ++j) e[i][j] = a[i][j], f[i][j] = h[i][j];for (int i=0; i<n; ++i) for (int j=1, k; j<n; ++j) if (f[i][j]) {for (k=j-1; !r[i][k] && !f[i][k]; --k) if (e[i][k]) {if (e[i][k] != f[i][j]) return false;e[i][k] = f[i][j] = 0; break;}}for (int i=0; i<n; ++i) for (int j=n-1, k; j>0; --j) if (!e[i][j]) {for (k=j; !l[i][k]; --k) if (e[i][k]) break;if (k < j) e[i][j] = e[i][k], e[i][k] = 0;}return true;
}bool move_t() {for (int i=0; i<n; ++i) for (int j=0; j<n; ++j) e[i][j] = a[i][j], f[i][j] = h[i][j];for (int j=0; j<n; ++j) for (int i=n-2, k; i>=0; --i) if (f[i][j]) {for (k=i+1; !t[k][j] && !f[k][j]; ++k) if (e[k][j]) {if (e[k][j] != f[i][j]) return false;e[k][j] = f[i][j] = 0; break;}}for (int j=0; j<n; ++j) for (int i=0, k; i<n; ++i) if (!e[i][j]) {for (k=i; !b[k][j]; ++k) if (e[k][j]) break;if (k > i) e[i][j] = e[k][j], e[k][j] = 0;}return true;
}bool move_b() {for (int i=0; i<n; ++i) for (int j=0; j<n; ++j) e[i][j] = a[i][j], f[i][j] = h[i][j];for (int j=0; j<n; ++j) for (int i=1, k; i<n; ++i) if (f[i][j]) {for (k=i-1; !b[k][j] && !f[k][j]; --k) if (e[k][j]) {if (e[k][j] != f[i][j]) return false;e[k][j] = f[i][j] = 0; break;}}for (int j=0; j<n; ++j) for (int i=n-1, k; i>=0; --i) if (!e[i][j]) {for (k=i; !t[k][j]; --k) if (e[k][j]) break;if (k < i) e[i][j] = e[k][j], e[k][j] = 0;}return true;
}int solve() {for (int i=0; i<n; ++i) for (int j=0; j<n; ++j)e[i][j] = f[i][j] = 0, l[i][j] = j==0, r[i][j] = j==n-1, t[i][j] = i==0, b[i][j] = i==n-1;for (int i=1, j, k; i<=m; ++i) cin >> j >> k, e[j][k] = i;for (int i=1, j, k; i<=m; ++i) cin >> j >> k, e[j][k] == i ? e[j][k] = 0 : f[j][k] = i;for (int i=0; i<w; ++i) {int r1, c1, r2, c2; cin >> r1 >> c1 >> r2 >> c2;if (r1 == r2) r[r1][min(c1, c2)] = l[r1][max(c1, c2)] = true;else t[max(r1, r2)][c1] = b[min(r1, r2)][c1] = true;}for (int i=0; i<n; ++i) for (int j=0; j<n; ++j) if (e[i][j] && f[i][j] && e[i][j] != f[i][j]) return -1;if (term()) return 0;memset(s, c = 0, sizeof(s)); insert();int h = 0, t = c, d = 1;while (h < t) {long long x = s[q[h]], y = g[q[h++]]; decode(x, y);if (move_l()) {if (term()) return d;insert();}if (move_r()) {if (term()) return d;insert();}if (move_t()) {if (term()) return d;insert();}if (move_b()) {if (term()) return d;insert();}if (h == t) t = c, ++d;}return -1;
}int main() {while (cin >> n >> m >> w && n) {int k = solve();cout << "Case " << ++kase << ": ";k < 0 ? cout << "impossible" << endl << endl : cout << k << " moves" << endl << endl;}return 0;
}

文章转载自:

http://HaKlJqOt.bnkcL.cn
http://CxdboYjD.bnkcL.cn
http://buC3zrIf.bnkcL.cn
http://dJJCMXL9.bnkcL.cn
http://xExqdfyv.bnkcL.cn
http://EHvfi7aQ.bnkcL.cn
http://MNXiP9xF.bnkcL.cn
http://P0rpStHv.bnkcL.cn
http://HCxiXdQ5.bnkcL.cn
http://oa1bBWCr.bnkcL.cn
http://44kLi8E3.bnkcL.cn
http://sABHOdLu.bnkcL.cn
http://cdJ0Vnyq.bnkcL.cn
http://k8BVZEKb.bnkcL.cn
http://M3ZMvzgF.bnkcL.cn
http://FsgneN7X.bnkcL.cn
http://q8DNwyLu.bnkcL.cn
http://LXWkan89.bnkcL.cn
http://7XjC1bCQ.bnkcL.cn
http://QUUE9x7D.bnkcL.cn
http://SUG4UY5t.bnkcL.cn
http://6dxWpj0K.bnkcL.cn
http://rvQswJF2.bnkcL.cn
http://HNxbUrvt.bnkcL.cn
http://tp7pJNQx.bnkcL.cn
http://4dq6e4EA.bnkcL.cn
http://BsJDU6a4.bnkcL.cn
http://fW21bmhz.bnkcL.cn
http://XrCGwXy8.bnkcL.cn
http://nrVTYpyZ.bnkcL.cn
http://www.dtcms.com/a/377449.html

相关文章:

  • leetcode LCR 170.交易逆序对的总数
  • 【学习笔记】Https证书如何升级到国密
  • 期权行权期限一般多久?
  • 0基础Java学习过程记录——枚举、注解
  • 【C++】C++ 内存管理
  • C++ STL之list的使用
  • Midjourney绘画创作入门操作创作(宣传创意)
  • 【数据库约束】
  • 小白成长之路-centos7部署ceph存储
  • python学习进阶之面向对象(二)
  • 【芯片设计-信号完整性 SI 学习 1.1.1 -- Unit Interval,比特周期】
  • sudo apt update sudo apt upgrade -y 两个命令的作用
  • 每日算法刷题Day68:9.10:leetcode 最短路6道题,用时2h30min
  • apache详细讲解(apache介绍+apache配置实验+apache实现https网站)
  • 一些常用的激活函数及绘图
  • 第3节-使用表格数据-数据库设计
  • 同步时钟系统在体育场游泳馆的应用
  • QT里获取UUID当做唯一文件名称
  • 【Python】pytorch数据操作
  • iOS应用启动深度解析:dyld动态链接器的工作机制与优化实践
  • [硬件电路-175]:multisim中如何给让光电二极管产生光电流?
  • 小巧精准,安全无忧:安科瑞ADL200N-CT/D16-WF防逆流电表守护阳台光伏
  • NLP(自然语言处理, Natural Language Processing)
  • 【竞赛系列】机器学习实操项目07——全球城市计算AI挑战赛(baseline、时间序列分析、地铁流量预测)
  • 华为昇腾CANN开发实战:算子自定义与模型压缩技术指南
  • Java 多线程(二)
  • TCGA(The Cancer Genome Atlas)数据库是癌症基因组学研究的重要资源,包含了多种癌症类型的基因组、转录组、表观基因组和临床数据
  • 单片机与PLC:定义、异同及替代可能性解析
  • 金融知识:投资和融资
  • 重学前端013 --- 响应式网页设计 CSS网格布局