UVa 810 - A Dicey Problem

时间限制:3.000秒

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=751


  就是一道BFS而已,在普通走迷宫的基础上多加了一个骰子的状态需要判断。

  题意是给出一个图,每个格子上都有一个数。然后给出一个起始位置,往这个位置上放一个骰子。然后给出这个骰子的初始状态,骰子的状态由两个数字表示,分别代表骰子顶面和正前面(从二维地图从下向上看为正前)的点数。如果骰子所在格子的相邻格子的数字等于当前骰子顶面的点数相同或者-1,那么骰子就可以滚动到这个格子上,如果格子的数字为0则表示该格子无法到达。要求求出一条路,使得骰子从起点出发能再走回起点,如果不存在,输出“No Solution Possible”。

  也不是很难,按照要求BFS就可以了,搜的时候记得存一下路以便最后输出,骰子状态的转换需要注意一下。


#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      

using std::stack;

struct status {
    int i, j, up, face; // 骰子当前位置和状态
    int last; // 上一个状态

    status() : i(0), j(0), up(0), face(0), last(-1) {}
    status(const int &i, const int &j, const int &up, const int &face, const int &last) : i(i), j(j), up(up), face(face), last(last) {}
};
int R, C;

// 骰子经过移动后对应的状态
int up_up[7][7], up_face[7][7];
int down_up[7][7], down_face[7][7];
int left_up[7][7], left_face[7][7];
int right_up[7][7], right_face[7][7];
inline void prepare() {
    int dice_left[7][7];
    dice_left[1][2] = 4, dice_left[1][3] = 2, dice_left[1][4] = 5, dice_left[1][5] = 3;
	dice_left[2][1] = 3, dice_left[2][3] = 6, dice_left[2][4] = 1, dice_left[2][6] = 4;
	dice_left[3][1] = 5, dice_left[3][2] = 1, dice_left[3][5] = 6, dice_left[3][6] = 2;
	dice_left[4][1] = 2, dice_left[4][2] = 6, dice_left[4][5] = 1, dice_left[4][6] = 5;
	dice_left[5][1] = 4, dice_left[5][3] = 1, dice_left[5][4] = 6, dice_left[5][6] = 3;
    dice_left[6][2] = 3, dice_left[6][3] = 5, dice_left[6][4] = 2, dice_left[6][5] = 4;

    for(int up = 1; up <= 6; ++up) for(int face = 1; face <= 6; ++face) if(up != face && up != 7 - face) {
        up_up[up][face] = face, up_face[up][face] = 7 - up;
        down_up[up][face] = 7 - face, down_face[up][face] = up;
        left_up[up][face] = 7 - dice_left[up][face], left_face[up][face] = face;
        right_up[up][face] = dice_left[up][face], right_face[up][face] = face;
    }
}

int goal_i, goal_j;
int pic[16][16];
status que[10000000];
int vis[16][16][7][7];

inline void bfs() {
    memset(vis, 0, sizeof(vis));
    int fro = 0, rear = 1;
    while(fro < rear) {
        status &cur = que[fro];
        if(cur.i == goal_i && cur.j == goal_j && fro) {
            stack
      
      
       
        st;
            int pt = fro;
            while(pt != -1) st.push(pt), pt = que[pt].last;

            for(int i = 0; !st.empty(); st.pop(), ++i) {
                int t = st.top();
                if(i % 9 == 0) {
                    if(i) printf(",\n");
                    printf("  (%d,%d)", que[t].i, que[t].j);
                }
                else printf(",(%d,%d)", que[t].i, que[t].j);
            }
            printf("\n");

            return;
        } else if(!vis[cur.i][cur.j][cur.up][cur.face]) {
            vis[cur.i][cur.j][cur.up][cur.face] = true;
            int &i = cur.i, &j = cur.j;

            if(pic[i - 1][j] == -1 || pic[i - 1][j] == cur.up) {
                que[rear].up = up_up[cur.up][cur.face], que[rear].face = up_face[cur.up][cur.face];
                que[rear].i = i - 1, que[rear].j = j, que[rear].last = fro;
                ++rear;
            }
            if(pic[i + 1][j] == -1 || pic[i + 1][j] == cur.up) {
                que[rear].up = down_up[cur.up][cur.face], que[rear].face = down_face[cur.up][cur.face];
                que[rear].i = i + 1, que[rear].j = j, que[rear].last = fro;
                ++rear;
            }
            if(pic[i][j - 1] == -1 || pic[i][j - 1] == cur.up) {
                que[rear].up = left_up[cur.up][cur.face], que[rear].face = left_face[cur.up][cur.face];
                que[rear].i = i, que[rear].j = j - 1, que[rear].last = fro;
                ++rear;
            }
            if(pic[i][j + 1] == -1 || pic[i][j + 1] == cur.up) {
                que[rear].up = right_up[cur.up][cur.face], que[rear].face = right_face[cur.up][cur.face];
                que[rear].i = i, que[rear].j = j + 1, que[rear].last = fro;
                ++rear;
            }
        }
        ++fro;
    }
    printf("  No Solution Possible\n");
}

int main() {
    prepare();

    char s[100];
    while(~scanf("%s", s) && strcmp(s, "END")) {
        puts(s);
        scanf("%d%d%d%d%d%d", &R, &C, &que[0].i, &que[0].j, &que[0].up, &que[0].face);
        goal_i = que[0].i, goal_j = que[0].j;

        for(int i = 0, ei = R + 2; i != ei; ++i) for(int j = 0, ej = C + 2; j != ej; ++j) pic[i][j] = 0;
        for(int i = 1; i <= R; ++i) for(int j = 1; j <= C; ++j) scanf("%d", &pic[i][j]);

        bfs();
    }
}

      
      
     
     
    
    
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值