【题目描述】
桌面上有两个特别的骰子。骰子的每一个面,都写了一个不同的数字。设第一个骰子上下左右前后分别为a1, a2, a3, a4, a5, a6,第二个骰子分别为b1, b2, b3, b4, b5, b6。保证每个数字在区间 [1, 6] 内,而且对于所有的i ≠ j都有ai ≠ aj, bi ≠ bj。特别地,每个骰子相对的两面数字之和都不会为7
一开始,两个骰子的摆放可能是不同的(即对应面的数字可能不同),所以Ddy想通过如下操作使两个骰子摆放变得相同
左转:以CG为轴向左转90°,使ACGE变成底部
右转:以DH为轴向右转90°,使BDHF变成底部
前转:以CD为轴向前转90°,使ABCD变成底部
后转:以GH为轴向后转90°,使EFHG变成底部
现在Ddy想知道达到目的的最小步数是多少。
【输入】
输入文件名:dice.in
多组数据,直到EOF
对于每组数据,两行,分别表示两个骰子的状态。
每行6个数分别a1, a2, …, a6和b1, b2, …, b6
【输出】
输出文件名:dice.out
对于每组数据输出一行,达到目的的最小步数。
无解则输出 -1
【输入样例】
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 5 6 4 3
1 2 3 4 5 6
1 4 2 5 3 6
【输出样例】
0
3
-1
说实话,这题就是状态有点特殊的广搜,没有什么思维难度,主要是考验你的代码实现能力。
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define ll long long #define il inline #define db double using namespace std; il int gi() { int x=0,y=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') y=-1; char ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*y; } il ll gl() { ll x=0,y=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') y=-1; char ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*y; } int t[100045][2]; int head,tail,aim,ans; bool vis[1000045],p; int c1,c2,c3,c4,c5,c6; il void turn_left() { if(p) return; int now=c4*100000+c3*10000+c1*1000+c2*100+c5*10+c6; // printf("now=%d\n",now); if(!vis[now]) { vis[now]=1; t[tail][0]=now; t[tail++][1]=t[head][1]+1; if(now==aim) { printf("%d\n",t[head][1]+1); p=1; } } } il void turn_right() { if(p) return; int now=c3*100000+c4*10000+c2*1000+c1*100+c5*10+c6; // printf("now=%d\n",now); if(!vis[now]) { vis[now]=1; t[tail][0]=now; t[tail++][1]=t[head][1]+1; if(now==aim) { printf("%d\n",t[head][1]+1); p=1; } } } il void turn_front() { if(p) return; int now=c6*100000+c5*10000+c3*1000+c4*100+c1*10+c2; // printf("now=%d\n",now); if(!vis[now]) { vis[now]=1; t[tail][0]=now; t[tail++][1]=t[head][1]+1; if(now==aim) { printf("%d\n",t[head][1]+1); p=1; } } } il void turn_back() { if(p) return; int now=c5*100000+c6*10000+c3*1000+c4*100+c2*10+c1; // printf("now=%d\n",now); if(!vis[now]) { vis[now]=1; t[tail][0]=now; t[tail++][1]=t[head][1]+1; if(now==aim) { printf("%d\n",t[head][1]+1); p=1; } } } int main() { freopen("dice.in","r",stdin); freopen("dice.out","w",stdout); int a1,a2,a3,a4,a5,a6,b1,b2,b3,b4,b5,b6; while(scanf("%d%d%d%d%d%d%d%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5,&a6,&b1,&b2,&b3,&b4,&b5,&b6)!=EOF) { p=0; memset(t,0,sizeof(t)); memset(vis,0,sizeof(vis)); head=0,tail=1; ans=0; aim=b1*100000+b2*10000+b3*1000+b4*100+b5*10+b6; t[0][0]=a1*100000+a2*10000+a3*1000+a4*100+a5*10+a6; if(t[0][0]==aim) { printf("0\n"); continue; } vis[t[0][0]]=1; // printf("%d %d\n",aim,t[0][0]); while(head!=tail) { c6=t[head][0]%10; t[head][0]/=10; c5=t[head][0]%10; t[head][0]/=10; c4=t[head][0]%10; t[head][0]/=10; c3=t[head][0]%10; t[head][0]/=10; c2=t[head][0]%10; t[head][0]/=10; c1=t[head][0]%10; // printf("%d %d %d %d %d %d\n",c1,c2,c3,c4,c5,c6); turn_left(); turn_right(); turn_front(); turn_back(); if(p) break; head++; } if(!p) printf("-1\n"); } return 0; }