题目:HDU5012Dice(隐式图搜索)
题目大意:给你一个两个色子,规定每个面的序号,现在给你这两个色子的每个面的颜色(a1,a2,a3,a4,a5,a5)(b1,b2,b3,b4,b5,b6)。现在要求比通过下面的四种旋转使得a序列和b序列一样。可以的话输出最少的旋转步数,不能输出-1.
解题思路:bfs + map判重。就是四种旋转的状态要弄清楚。
代码:
#include <cstdio> #include <cstring> #include <map> using namespace std; const int N = 6; const int maxn = 30; const int dir[4][N] = {{3, 2, 0, 1, 4, 5}, {2, 3, 1, 0, 4, 5}, {5, 4, 2, 3, 0, 1}, {4, 5, 2, 3, 1, 0}}; struct State { int dice[N]; }st[maxn]; int ans; int p[maxn]; map<int ,int> vis; int hash (State a) { int sum = 0; for (int i = 0; i < N; i++) sum = sum * 10 + a.dice[i]; return sum; } int bfs () { int front, rear; front = 0; rear = 1; vis.clear(); p[0] = 0; vis[hash (st[0])] = 1; while (front < rear) { if (hash (st[front]) == ans) return front; for (int i = 0; i < 4; i++) { for (int j = 0; j < N; j++) st[rear].dice[j] = st[front].dice[dir[i][j]]; int tmp = hash (st[rear]); if (!vis[tmp]) { vis[tmp] = 1; p[rear] = p[front] + 1; rear++; } } front++; } return -1; } int main () { int num; while (scanf ("%d%d%d%d%d%d", &st[0].dice[0], &st[0].dice[1], &st[0].dice[2], &st[0].dice[3], &st[0].dice[4], &st[0].dice[5]) != EOF) { ans = 0; for (int i = 0; i < N; i++) { scanf ("%d", &num); ans = ans * 10 + num; } int flag = bfs(); if (flag == -1) printf ("-1\n"); else printf ("%d\n", p[flag]); } return 0; }