URAL 1016 Cube on the Walk 搜索题

8 篇文章 0 订阅
  这是一道搜索题,题目意思是给你一个棋盘,一个立方体,一个起点,一个终点,然后立方体的每个面都有值,问你从起点到终点最少的值是多少,并输出路径。每次翻滚计算的是底面的值。因为是立方体,所以以每一个面作为底面的时候,有四种状态,而每种状态又有前后左右翻滚的四种状态,所以总共是16种(除去本身和不相连的面,不然是24种),这些状态我都是纯手推的。至于输出路径,用path数组就可以了,不过要注意因为一个地方会重复翻滚,所以状态要多记录几个,不仅仅记录坐标。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define maxn 9
#define inf 1000000005
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;

int sx, sy, ex, ey, nn, num[6], dis[maxn][maxn][6][6], pathx[maxn][maxn][6][6], pathy[maxn][maxn][6][6], pathd[maxn][maxn][6][6], pathz[maxn][maxn][6][6], js[maxn][maxn], dir[6][6][4] = {{{0, 0, 0, 0}, {0, 0, 0, 0}, {4, 3, 2, 5}, {5, 4, 3, 2}, {2, 5, 4, 3}, {3, 2, 5, 4}}, {{0, 0, 0, 0}, {0, 0, 0, 0}, {4, 5, 2, 3}, {5, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 2}}, {{1, 5, 0, 3}, {0, 3, 1, 5}, {0, 0, 0, 0}, {5, 0, 3, 1}, {0, 0, 0, 0}, {3, 1, 5, 0}}, {{1, 2, 0, 4}, {0, 4, 1, 2}, {4, 1, 2, 0}, {0, 0, 0, 0}, {2, 0, 4, 1}, {0, 0, 0, 0}}, {{1, 3, 0, 5}, {0, 5, 1, 3}, {0, 0, 0, 0}, {5, 1, 3, 0}, {0, 0, 0, 0}, {3, 0, 5, 1}}, {{1, 4, 0, 2}, {0, 2, 1, 4}, {4, 0, 2, 1}, {0, 0, 0, 0}, {2, 1, 4, 0}, {0, 0, 0, 0}}}, ox[4] = {-1, 0, 1, 0}, oy[4] = {0, -1, 0, 1}, mins, fan[6] = {1, 0, 4, 5, 2, 3};

struct node
{
    int x, y;
}nd[260];

void res(int a, int b, int c, int d)
{
    int x = pathx[a][b][c][d];
    int y = pathy[a][b][c][d];
    int di = pathd[a][b][c][d];
    int z = pathz[a][b][c][d];
    if(x == sx&&y == sy&&di == 3&&z == 0)
    {
        nd[nn].x = x;
        nd[nn++].y = y;
        nd[nn].x = a;
        nd[nn++].y = b;
        return;
    }
    res(x, y, di, z);
    nd[nn].x = a;
    nd[nn++].y = b;
}

struct cube
{
    int x, y, di, z, v, pre;
};

void bfs(int x, int y, int p, int di, int z, int v)
{
    queue<struct cube> q;
    struct cube tt;
    dis[x][y][di][z] = v;
    tt.x = x, tt.y = y, tt.di = di;
    tt.z = z, tt.v = v, tt.pre = p;
    q.push(tt);
    while(!q.empty())
    {
        struct cube tmp = q.front();
        q.pop();
        if(tmp.v >= mins)
            continue;
        if(tmp.x == ex&&tmp.y == ey&&mins > tmp.v)
        {
            mins = tmp.v;
            nn = 0;
            res(tmp.x, tmp.y, tmp.di, tmp.z);
            continue;
        }
        int nowdi = tmp.di, nowz = tmp.z;
        int nowx = tmp.x, nowy = tmp.y;
        int nowv = tmp.v, pre = tmp.pre;
        for(int i = 0;i < 4;i++)
        {
            int tz;
            if(!i)
                tz = nowdi;
            else if(i == 2)
                tz = fan[nowdi];
            else
                tz = nowz;
            if(dir[nowdi][nowz][i] != pre&&nowx + ox[i] >= 0&&nowx + ox[i] < 8&&nowy + oy[i] >= 0&&nowy + oy[i] < 8&&dis[nowx + ox[i]][nowy + oy[i]][dir[nowdi][nowz][i]][tz] > nowv + num[dir[nowdi][nowz][i]])
            {
                dis[nowx + ox[i]][nowy + oy[i]][dir[nowdi][nowz][i]][tz] = nowv + num[dir[nowdi][nowz][i]];
                pathx[nowx + ox[i]][nowy + oy[i]][dir[nowdi][nowz][i]][tz] = nowx;
                pathy[nowx + ox[i]][nowy + oy[i]][dir[nowdi][nowz][i]][tz] = nowy;
                pathd[nowx + ox[i]][nowy + oy[i]][dir[nowdi][nowz][i]][tz] = nowdi;
                pathz[nowx + ox[i]][nowy + oy[i]][dir[nowdi][nowz][i]][tz] = nowz;
                struct cube jj;
                jj.di = dir[nowdi][nowz][i], jj.pre = nowdi, jj.v = nowv + num[dir[nowdi][nowz][i]];
                jj.x = nowx + ox[i], jj.y = nowy + oy[i], jj.z = tz;
                q.push(jj);
            }
        }
    }
    return;
}

int main()
{
    char a, b;
    int c, d;
    while(~scanf("%c%d%*c%c%d%d%d%d%d%d%d%*c", &a, &c, &b, &d, &num[0], &num[1], &num[5], &num[4], &num[3], &num[2]))
    {
        sx = 8 - c;
        sy = a - 'a';
        ex = 8 - d;
        ey = b - 'a';
        mins = inf;
        for(int i = 0;i < 8;i++)
            for(int j = 0;j < 8;j++)
                for(int k = 0;k < 6;k++)
                    for(int r = 0;r < 6;r++)
                        dis[i][j][k][r] = inf;
        bfs(sx, sy, 7, 3, 0, num[3]);
        printf("%d", mins);
        for(int i = 0;i < nn;i++)
            printf(" %c%d", nd[i].y + 'a', 8 - nd[i].x);
        printf("\n");
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值