A Dicey Problem 骰子难题(Uva 810)
题目描述:https://uva.onlinejudge.org/external/8/810.pdf
把一个骰子放在一个M x N的地图上,让他按照规定滚动,求滚回原点的最短路径。
思路: 记忆化搜索(我这里用的dfs深度优先搜索)
难点:
如何推导骰子的状态
我没有用打表,而是先用build_dice()初始化二维数组dice, 这样,当我们有骰子的顶面top,正面face, 就可以通过dice[top][face] 获得对应的右面,由此,就可以实现骰子的旋转。rotate()函数实现骰子的旋转,给它top, face, 和旋转的方向(前,后,左,右), 它会返回旋转后骰子的top, face.
记忆化搜索要多一个状态记录骰子的状态
说白了就是记录访问状态的数组vis要多两个维度分别记录top, face,因为top, face一旦固定,骰子就固定了
Note: 输出的格式也要稍微注意一下,锁进、末尾的逗号,换行要处理好。
#include <iostream>
#include <cstdio>
#include <vector>
#include <utility>
#include <cstring>
using namespace std;
const int MAXN = + ;
int b[MAXN][MAXN], R, C, sx, sy, st, sf, len;
int dx[] = {, -, , }, dy[] = {, , -, }, dice[][];
bool vis[MAXN][MAXN][][], ok, first;
vector<pair<int, int> > path;
void build_dice() { //dice[top][face] = right
dice[][] = ;
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
if (i == j) continue;
if (dice[i][ - j]) dice[i][j] = - dice[i][ - j];
if (dice[i][j]) {
dice[j][i] = - dice[i][j];
dice[i][dice[i][j]] = - j;
}
}
}
}
pair<int, int> rotate(int top, int face, int di) {
pair<int, int> n_tf;
if (di == ) {
n_tf.second = face;
n_tf.first = - dice[top][face];
}
else if (di == ) {
n_tf.first = face;
n_tf.second = - top;
}
else if (di == ) {
n_tf.second = face;
n_tf.first = dice[top][face];
}
else {
n_tf.second = top;
n_tf.first = - face;
}
return n_tf;
}
bool inside(int x, int y) {
return x > && y > && x <= R && y <= C;
}
void dfs(int x, int y, int t, int f) {
path.push_back(make_pair(x, y));
if (x == sx && y == sy)
if (first) first = ;
else { ok = ; return;}
vis[x][y][t][f] = ;
for (int i = ; i < ; i++) {
pair<int, int> nextp = rotate(t, f, i);
int nx = x + dx[i], ny = y + dy[i];
int nt = nextp.first, nf = nextp.second;
if (inside(nx, ny) && (!vis[nx][ny][nt][nf] || (nx == sx && ny == sy)) && (t == b[nx][ny] || b[nx][ny] == -)) {
dfs(nx, ny, nt, nf);
}
if (ok) return;
}
vis[x][y][t][f] = ;
path.pop_back();
}
int main() {
build_dice();
char name[];
while (scanf("%s", name) == && strcmp(name, "END")) {
scanf("%d%d%d%d%d%d", &R, &C, &sx, &sy, &st, &sf);
memset(vis, , sizeof(vis));
memset(b, , sizeof(b));
path.clear(); ok = ; first = ;
for (int i = ; i <= R; i++)
for (int j = ; j <= C; j++)
scanf("%d", &b[i][j]);
dfs(sx, sy, st, sf);
len = path.size();
printf("%s", name);
if (ok)
for (int i = ; i < len; i++) {
if (i % == ) {
if (i >= ) printf(",");
printf("\n (%d,%d)", path[i].first, path[i].second);
}
else printf(",(%d,%d)", path[i].first, path[i].second);
}
else printf("\n No Solution Possible");
printf("\n");
}
return ;
}
A Dicey Problem 骰子难题(Uva 810)的更多相关文章
- UVA 810 - A Dicey Problem(BFS)
UVA 810 - A Dicey Problem 题目链接 题意:一个骰子,给你顶面和前面.在一个起点,每次能移动到周围4格,为-1,或顶面和该位置数字一样,那么问题来了,骰子能不能走一圈回到原地, ...
- poj 1872 A Dicey Problem WA的代码,望各位指教!!!
A Dicey Problem Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 832 Accepted: 278 Des ...
- UVA-810 A Dicey Problem (BFS)
题目大意:滚骰子游戏,骰子的上面的点数跟方格中的数相同时或格子中的数是-1时能把格子滚过去,找一条从起点滚到起点的路径. 题目大意:简单BFS,状态转移时细心一些即可. 代码如下; # include ...
- poj1872A Dicey Problem
Home Problems Status Contest 284:28:39 307:00:00 Overview Problem Status Rank A B C D E F G H ...
- Uva - 810 - A Dicey Problem
根据状态进行bfs,手动打表维护骰子滚动. AC代码: #include <iostream> #include <cstdio> #include <cstdlib&g ...
- UVA 810 A Dicey Promblem 筛子难题 (暴力BFS+状态处理)
读懂题意以后还很容易做的, 和AbbottsRevenge类似加一个维度,筛子的形态,可以用上方的点数u和前面的点数f来表示,相对的面点数之和为7,可以预先存储u和f的对应右边的点数,点数转化就很容易 ...
- UVA 11991 Easy Problem from Rujia Liu?【STL】
题目链接: option=com_onlinejudge&Itemid=8&page=show_problem&problem=3142">https://uv ...
- UVa 11375 - Matches
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- UVA 567 Risk【floyd】
题目链接: option=com_onlinejudge&Itemid=8&page=show_problem&problem=508">https://uva ...
随机推荐
- CI 笔记 datagrid的调用,不支持多页面多次调用js
在导航列表中,调用datagrid时,如果用js加载datagrid时,不知为何,报“404错误”找不到网页, 用datagrid时,用网页的形式调用,则没有问题. ----------------- ...
- 7-1 DBA顾问培训内容@20141230
1, 逻辑读还是物理读? 查询语句的实际执行计划. F5 预计执行计划. --如何产生实际执行计划 ??. --Session收集指令. workload repository report fo ...
- CSS Positioning(定位)
Positioning(定位) CSS定位属性允许你为一个元素定位.它也可以将一个元素放在另一个元素后面,并指定一个元素的内容太大时,应该发生什么. 元素可以使用的顶部,底部,左侧和右侧属性定位.然而 ...
- ubuntu安装配置搜狗拼音输入法
进入下载目录,在终端执行安装 $sudo dpkg -i sogou_pinyin_linux_1.0.0.0033_amd64.deb 安装过程会出现 依赖关系问题 2 修复依赖关系完成搜狗拼 ...
- php完整验证码代码
<?php require_once 'string.func.php'; //通过GD库做验证码 /** *添加验证文字 * @param int $type * @param int $le ...
- http://src.chromium.org/svn/ 定制chrome浏览器教程及源码
chromium 官网登不进去,最近在学习chrome插件制作,网上教程很多大多没有源码 其实作为开源软件 官方提供了全部源码地址:http://src.chromium.org/svn/ PRESU ...
- python核心编程2第二章课后练习
2-1 变量, print 和字符串格式化运算符.启动交互式解释器.给一些变量赋值(字符串,数值等等)并通过输入变量名显示它们的值.再用 print 语句做同样的事.这二者有何区别? 也尝试着使用字符 ...
- 结合rpyc使用python实现动态升级的方法
动态升级,就是程序不退出的情况下,将其代码更新的策略.假设集群含有多个机器,然后每个机器部署一套程序,当升级的时候就要去所有的上面部署一把. (1)有个包装程序专门负责接口并检查是否需要更新,当需要更 ...
- log4j详细配置说明
log4j配置祥解 第一步:加入log4j-1.2.8.jar到lib下.第二步:在CLASSPATH下建立log4j.properties.内容如下:1 log4j.rootCategory=INF ...
- JUnit扩展:引入新注解Annotation
发现问题 JUnit提供了Test Suite来帮助我们组织case,还提供了Category来帮助我们来给建立大的Test Set,比如BAT,MAT, Full Testing. 那么什么情况下, ...