题目描述: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)的更多相关文章

  1. UVA 810 - A Dicey Problem(BFS)

    UVA 810 - A Dicey Problem 题目链接 题意:一个骰子,给你顶面和前面.在一个起点,每次能移动到周围4格,为-1,或顶面和该位置数字一样,那么问题来了,骰子能不能走一圈回到原地, ...

  2. poj 1872 A Dicey Problem WA的代码,望各位指教!!!

    A Dicey Problem Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 832   Accepted: 278 Des ...

  3. UVA-810 A Dicey Problem (BFS)

    题目大意:滚骰子游戏,骰子的上面的点数跟方格中的数相同时或格子中的数是-1时能把格子滚过去,找一条从起点滚到起点的路径. 题目大意:简单BFS,状态转移时细心一些即可. 代码如下; # include ...

  4. 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 ...

  5. Uva - 810 - A Dicey Problem

    根据状态进行bfs,手动打表维护骰子滚动. AC代码: #include <iostream> #include <cstdio> #include <cstdlib&g ...

  6. UVA 810 A Dicey Promblem 筛子难题 (暴力BFS+状态处理)

    读懂题意以后还很容易做的, 和AbbottsRevenge类似加一个维度,筛子的形态,可以用上方的点数u和前面的点数f来表示,相对的面点数之和为7,可以预先存储u和f的对应右边的点数,点数转化就很容易 ...

  7. UVA 11991 Easy Problem from Rujia Liu?【STL】

    题目链接: option=com_onlinejudge&Itemid=8&page=show_problem&problem=3142">https://uv ...

  8. UVa 11375 - Matches

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  9. UVA 567 Risk【floyd】

    题目链接: option=com_onlinejudge&Itemid=8&page=show_problem&problem=508">https://uva ...

随机推荐

  1. SQL打印全年日历

    数据库环境:SQL SERVER 2008R2 我之前有写过打印本月日历的SQL,里头有详细的说明.具体请参考前面的博文——生成本月日历. 全年日历只是在本月日历的基础上加了月信息,并按月份分组求得. ...

  2. python基础(目录)

    1.数据库操作入门 2.网络编程入门 3.编码规范 4.测试

  3. 对有状态bean和无状态bean的理解(转)

    现实中,很多朋友对两种session bean存在误解,认为有状态是实例一直存在,保存每次调用后的状态,并对下一次调用起作用,而认为无状态是每次调用实例化一次,不保留用户信息.仔细分析并用实践检验后, ...

  4. Java环境变量配置&解决版本不一致问题

    之前用Myeclipse编译运行Java没有问题 但是突然想用简单点的NotePad++以及cmd直接编译运行Java 这就让我倒腾了一晚上 先说下问题的解决,再总结下查阅的一些知识. 1.进行win ...

  5. ubuntu下提示/boot空间不足,解决办法

    在安装 ubuntu的时候 , 给/boot文件目录分配空间的时候,是100M,/boot可以单独分成一个区,也可以不单独分,在/(根目录)下也会自动为其创建一个boot目录.顺便提一下,linux分 ...

  6. PHP页面静态化入门

    <?php /** *PHP页面静态化分为以下步骤: *1.打开输出控制缓存 *2.返回输出缓存区的内容 *3.将一个字符串写入文件 *4.冲刷出缓存区的内容 */ //1.打开输出控制缓存 o ...

  7. 求LR(0)文法的规范族集和ACTION表、GOTO表的构造算法

    原理 数据结构 // GO private static Map<Map<Integer,String>,Integer> GO = new HashMap<Map< ...

  8. Linux内存映射(mmap)系列(1)

    看到同事的代码中出现了mmap.所以自己私下学习学习,研究研究..... http://www.cnblogs.com/lknlfy/archive/2012/04/27/2473804.html ( ...

  9. 学习Swift--枚举的初步认识 --个人备忘 大神勿喷

    枚举定义了一个通用类型的一组相关值,使你可以在你的代码中以一种安全的方式来使用这些值. // 定义枚举的语法 enum Chips { // 定义了薯片的枚举,包含了3种口味的成员 case Toma ...

  10. 用VS2010编写的C++程序,在其他电脑上无法运行,提示缺少mfc100.dll的解决办法

    问题: 在自己电脑上用VS2010编写的VC++程序(使用MFC库),不能在其他电脑上运行.双击提示: "无法启动此程序,因为计算机中丢失mfc100.dll 尝试重新安装该程序以解决此问题 ...