UVa 10384 - The Wall Pushers
链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1325
题意:
从迷宫的S处出发,每次可以往东、南、西、北4个方向之一前进。如果前方有墙壁,游戏者可以把墙壁往前推一格。
如果有两堵或者多堵连续的墙,则不能推动。另外,游戏者也不能推动游戏区域边界上的墙。
用最少的步数走出迷宫(边界处没有墙的地方就是出口)。迷宫总是有4行6列,多解时任意输出一个移动序列即可。
分析:
广搜 + 状态压缩。
因为总墙数只有58,所以可以用一个long long型变量来储存一个状态。
用set来判重。
具体实现见代码。
代码:
#include <cstdio>
#include <queue>
#include <set>
using namespace std; typedef long long int LLI;
const int dr[] = {-, , , }; //上下左右
const int dc[] = {, , -, };
const char dir[+] = "NSWE"; struct NODE {
int r, c, f, pre; //所在行,所在列,父方向,父结点
char d; //移动方向
LLI state; //当前状态
} node[]; int wall[][][]; //wall[r][c][d] : 第r行第c列d方向的墙的编号 void constant(){
/* 给墙编号时墙的储存方式:
_ _ _
|_|_|_|
|_|_|_|
|_|_|_|
*/
const int cdr[] = {-, , , }; //上下左右
const int cdc[] = {, , -, };
int id = , code[+][+];
for(int c = ; c < ; c += ) code[][c] = id++; //给每一堵墙编号
for(int r = ; r < ; r++){
for(int c = ; c < ; c++) code[r][c] = id++;
}
for(int r = ; r < ; r++){ //获取wall数组
for(int c = ; c < ; c += ){
int t = r - , i = (c - ) / ;
for(int d = ; d < ; d++){
int fr = r + cdr[d], fc = c + cdc[d];
wall[t][i][d] = code[fr][fc];
}
}
}
} void output(int n){ //输出路径
if(node[n].pre) output(node[n].pre);
printf("%c", node[n].d);
} void bfs(){
node[].f = -;
set<LLI> S[][];
S[node[].r][node[].c].insert(node[].state);
queue<int> Q;
Q.push();
int np = ;
while(Q.size()){
int f = Q.front(); Q.pop();
int r = node[f].r;
int c = node[f].c;
LLI& s = node[f].state;
for(int d = ; d < ; d++){
if(d == node[f].f) continue; //避免向父方向返回
LLI state = s;
bool valid = true;
int fr = r + dr[d], fc = c + dc[d];
if(state & 1LL << wall[r][c][d]){ //若前面有墙
if(fr < || fr > || fc < || fc > ) valid = false; //超出边界
else if(state & 1LL << wall[fr][fc][d]) valid = false; //多堵墙连续
else{ //移动该墙
state |= 1LL << wall[fr][fc][d];
state ^= 1LL << wall[r][c][d];
}
}
if(!valid) continue;
if(fr < || fr > || fc < || fc > ){ //找到出口
node[np].d = dir[d];
node[np].pre = f;
output(np);
printf("\n");
return;
}
if(S[fr][fc].count(state)) continue;
S[fr][fc].insert(state);
node[np].r = fr;
node[np].c = fc;
node[np].f = d ^ ; //d的相反方向
node[np].d = dir[d];
node[np].pre = f;
node[np].state = state;
Q.push(np++);
}
}
} int main(){
constant();
const int wei[] = {, , , };
while(scanf("%d%d", &node[].c, &node[].r) && node[].r){
node[].r--; node[].c--; node[].state = ;
for(int r = ; r < ; r++){
for(int c = ; c < ; c++){
int n;
scanf("%d", &n);
for(int d = ; d < ; d++){ //判断上下左右是否有墙
if(n & wei[d]) node[].state |= 1LL << wall[r][c][d];
}
}
}
bfs();
}
return ;
}
UVa 10384 - The Wall Pushers的更多相关文章
- UVA - 10384 The Wall Pusher(推门游戏)(IDA*)
题意:从起点出发,可向东南西北4个方向走,如果前面没有墙则可走:如果前面只有一堵墙,则可将墙向前推一格,其余情况不可推动,且不能推动游戏区域边界上的墙.问走出迷宫的最少步数,输出任意一个移动序列. 分 ...
- UVA10384-The Wall Pushers(迭代加深搜索)
Problem UVA10384-The Wall Pushers Accept: 199 Submit: 1546Time Limit: 10000 mSec Problem Descripti ...
- UVA-10384 The Wall Pushers (IDA*)
题目大意:走迷宫,遇到墙时可以推着墙走,但墙后还是墙时便不能推.求出一条任意的最短路径. 题目分析:这道题出的比较人性,输入的时候便是将四周的墙用二进制数表示好了,其实这样减轻了做题人的负担.IDA* ...
- UVa 900 - Brick Wall Patterns
题目大意:用1*2的砖头建n*2的墙,问有多少种不同的砖头排列方式?与斐波那契序列相似. #include <cstdio> #define MAXN 60 #define N 50 un ...
- 【暑假】[深入动态规划]UVa 10618 Fixing the Great Wall
UVa 10618 Fixing the Great Wall 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=361 ...
- UVa 11040 (水题) Add bricks in the wall
题意: 45块石头如图排列,每块石头上的数等于下面支撑它的两数之和,求其余未表示的数. 分析: 首先来计算最下面一行的数,A71 = A81 + A82 = A91 + 2A92 + A93,变形得到 ...
- UVa 1303 - Wall
题目:有非常多点.修一座最短的围墙把素有点围起来,使得全部点到墙的距离不小于l. 分析:计算几何,凸包. 假设.没有距离l的限制.则答案就是凸包的周长了.有了距离限制事实上是添加了2*π*l. 证明: ...
- UVA 11040 Add bricks in the wall
https://vjudge.net/problem/UVA-11040 找规律 #include<cstdio> using namespace std; ][]; int main() ...
- UVA 11040 Add bricks in the wall(线性组合)
砖块上的数字最终都可以看作是最后一行的线性组合,独立变元最多9个. 这类题的一般做法,线性组合都可以列出方程然后高斯消元. 对于这道题,只要确定最后一行剩下的4个变量就好了,对于最后一行的j位置,它对 ...
随机推荐
- java--多线程之后台线程
public class ThreadDaemon { /** * @param args * 后台线程在主进程结束后,也会退出 */ public static void main(String[] ...
- [转]Consuming a OData Service in a Client Application (WCF Data Services)
本文转自:https://msdn.microsoft.com/zh-tw/library/dd728282(v=vs.103).aspx WCF Data Services 5.0 其他版本 ...
- 理解Xaml标记语言
理解XAML XAML基于XAML,因而具有与XAML相似的特性.在XAMl中,同样必须区分大小写,但是Xaml以.xaml作为扩展名,表示这是一个应用程序的标记扩展文件.WPF中的XAML主要用于创 ...
- log4js日志
安装log4js:npm install log4js express中配置log4js中间件: var log = require("./modules/utils/logUtil.js& ...
- react-native学习之环境安装
1.首先是java环境安装-安装JDK 2.安装Android-SDK,推荐以下地址:http://tools.android-studio.org/index.php/sdk 然后打开SDK Man ...
- 二:Redis数据类型
一.nosql(非关系性数据库): mongoDB hbase redis nulch hive pig mahout zookeeper 二:redis 数据类型 1.存储string: 常用命令 ...
- redis(8)集群简介
一.集群 互联网每天都会产生大量的数据,单实例已经不能满足需求.但是如果依赖于硬件成本的提升,那就不是所有人能够负担的起的. 集群这个时候出现,一定程度上解决了这个问题.它通过互联网,将多个单实例连接 ...
- Oracle Spatial GIS相关研究
1.Oracle Spatial 概念相关 Oracle Spatial 是Oracle 数据库强大的核心特性,包含了用于存储矢量数据类型.栅格数据类型和持续拓扑数据类型的原生数据类型.Oracle ...
- C Primer Plus note8
error: too few arguments to function 'imax'| 运行上面的代码,产生了下面的错误: 中文翻译是:函数imax()中的参数太少. 查看imax()函数声明,发现 ...
- JavaScript this指向相关内容
1,默认绑定this指向windw对象 看代码: function test(C){ var a = 123 function b(){}; } 在预编译环节当中. OA{ arguments:[1] ...