Description
Input
Output
一个整数:答案
Sample Input
e2 e3 0 8 1 2 1 1
Sample Output
5
Solution
其实,这题除了考算法以外,考的主要是程序实现能力和折纸能力。
首先折一个立方体,按照题目的顺序给前面,后面,上面……依次标上1~6
接着用这个立方体模拟一下怎么滚的,就会发现往四个方向滚之后,六面依次变成了什么,打个表(题目关键就在这个表)
1,2,3,4分别代表左,前,右,后。
int bl[5][7]={{0,0,0,0,0,0,0},
{0,1,2,6,3,4,5},
{0,5,3,1,4,2,6},
{0,1,2,4,5,6,3},
{0,3,5,2,4,1,6}};
然后就直接BFS,SPFA暴力修改,注意F数组和标记数组不仅要记录坐标,还要记录立方体的状态。只要记两个面应该就够了,而我记录了六个面,于是就成了八维数组
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int d[64*100][9],ddd[5]={0,1,0,-1,0},dddd[5]={0,0,1,0,-1},b[7],ans=100000000;
int bl[5][7]={{0,0,0,0,0,0,0},
{0,1,2,6,3,4,5},
{0,5,3,1,4,2,6},
{0,1,2,4,5,6,3},
{0,3,5,2,4,1,6}};
bool bz[9][9][7][7][7][7][7][7];
int f[9][9][7][7][7][7][7][7];
int main()
{
char ch1,ch2;int y2;
scanf("%c%d %c%d %d %d %d %d %d %d",&ch1,&d[1][8],&ch2,&y2,&b[1],&b[2],&b[3],&b[4],&b[5],&b[6]);
fo(i,1,6) d[1][i]=i;
int x2=ch2-96;d[1][7]=ch1-96;memset(f,127,sizeof(f));
f[d[1][7]][d[1][8]][1][2][3][4][5][6]=b[5];
for(int i=0,j=1;i<j;)
{
i++;
fo(k,1,4)
{
int x=d[i][7]+ddd[k],y=d[i][8]+dddd[k],c[7];
fo(l,1,6) c[l]=d[i][bl[k][l]];
if(x>0&&x<=8&&y>0&&y<=8&&f[x][y][c[1]][c[2]][c[3]][c[4]][c[5]][c[6]]>f[d[i][7]][d[i][8]][d[i][1]][d[i][2]][d[i][3]][d[i][4]][d[i][5]][d[i][6]]+b[c[5]])
{
f[x][y][c[1]][c[2]][c[3]][c[4]][c[5]][c[6]]=f[d[i][7]][d[i][8]][d[i][1]][d[i][2]][d[i][3]][d[i][4]][d[i][5]][d[i][6]]+b[c[5]];
if(x==x2&&y==y2) ans=min(ans,f[x][y][c[1]][c[2]][c[3]][c[4]][c[5]][c[6]]);
if (bz[x][y][c[1]][c[2]][c[3]][c[4]][c[5]][c[6]]==0)
{
bz[x][y][c[1]][c[2]][c[3]][c[4]][c[5]][c[6]]=1;
d[++j][7]=x;d[j][8]=y;fo(l,1,6) d[j][l]=c[l];
}
}
}
bz[d[i][7]][d[i][8]][d[i][1]][d[i][2]][d[i][3]][d[i][4]][d[i][5]][d[i][6]]=0;
}
printf("%d",ans);
}