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位置,它对 ...
随机推荐
- ansible roles 目录规范
我的ansible roles项目的目录结构: (ansible_venv) [root@localhost ansible_home]# tree ansible_playbooks/ ansibl ...
- Java API 之 Properties 类
1.简介 在项目中我们经常看到一种格式极其干净的配置文件,如:config.properties.在Java的体系结构中也提供了API对properties文件进行读取和写入等操作,即:Propert ...
- Java温故而知新(5)设计模式详解(23种)
一.设计模式的理解 刚开始“不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把锁的模式,目 ...
- php编程--二叉树遍历算法实现
今天使用php来实现二叉树的遍历 创建的二叉树如下图所示 php代码如下所示: <?php class Node { public $value; public $child_l ...
- pv-remjs的快速开始
pv-remjs 这是一个移动端适配的工具类,采用rem布局的方式 ## 快速开始 在html文件中引入,先查看版本`<script src= "https://unpkg.com/p ...
- 2-4 Sass的函数功能-颜色函数
RGB颜色函数-RGB()颜色函数 在 Sass 的官方文档中,列出了 Sass 的颜色函数清单,从大的方面主要分为 RGB , HSL 和 Opacity 三大函数,当然其还包括一些其他的颜色函数, ...
- 最长公共子序列(LCS)思维导图
- 【阿里云产品公测】OpenSearch初体验
OpenSearch是一个非常有意义的功能,对于很多数据量较大的站点, SF2< 如果搜索功能自己做的话,或者用数据库里的查询语句,首先效率低下,而且占用资源. ); <Le6 另 ...
- 【读书笔记】思维导图 Talk Like Ted
- GreenDao 初体验
GreenDao 使用 环境搭建(android studio) project的build.gradle buildscript { repositories { google() jcenter( ...