这是一道搜索题,题目意思是给你一个棋盘,一个立方体,一个起点,一个终点,然后立方体的每个面都有值,问你从起点到终点最少的值是多少,并输出路径。每次翻滚计算的是底面的值。因为是立方体,所以以每一个面作为底面的时候,有四种状态,而每种状态又有前后左右翻滚的四种状态,所以总共是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;
}