祝大家新年快乐,相信在新的一年里一定有我们自己的梦!
这是一个简化的魔板问题,只需输出步骤即可。
玩具(Toy)
描述
ZC神最擅长逻辑推理,一日,他给大家讲述起自己儿时的数字玩具。
该玩具酷似魔方,又不是魔方。具体来说,它不是一个3 * 3 * 3的结构,而是4 * 2的结构。
按照该玩具约定的玩法,我们可反复地以如下三种方式对其做变换:
A. 交换上下两行。比如,图(a)经此变换后结果如图(b)所示。
B. 循环右移(ZC神从小就懂得这是什么意思的)。比如,图(b)经此变换后结果如图(c)所示。
C. 中心顺时针旋转。比如,图(c)经此变换后结果如图(d)所示。
ZC神自小就是这方面的天才,他往往是一只手还没揩干鼻涕,另一只手已经迅速地将处于任意状态的玩具复原至如图(a)所示的初始状态。物质极其匮乏的当年,ZC神只有一个这样的玩具;物质极大丰富的今天,你已拥有多个处于不同状态的玩具。现在,就请将它们全部复原吧。
输入
第一行是一个正整数,即你拥有的魔方玩具总数N。
接下来共N行,每行8个正整数,表示该玩具的当前状态。
这里,魔方状态的表示规则为:前四个数自左向右给出魔方的第一行,后四个数自右向左给出第二行。比如,初始状态表示为“1 2 3 4 5 6 7 8”。
输出
共N行,各含一个整数,依次对应于复原各玩具所需执行变换的最少次数。
特别地,若某个玩具不可复原,则相应行输出-1。
输入样例
2
1 2 3 4 5 6 7 8
8 6 3 5 4 2 7 1
输出样例
0
2
限制
对于60%的数据,N = 1
对于100%的数据,1 <= N <= 1,000
时间:1 sec
空间:20MB
提示
状态转换图及其搜索
解法可以参看我的另一篇文章:ACM/ICPC 之 BFS(离线)+康拓展开 (HDU1430-魔板)
具体代码如下:
1 //玩具(Toy),类似魔板问题,但只需输出步骤数即可 2 //Time:28Ms Memory:13376MB (No.10) 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 using namespace std; 7 #define MAX 40321 8 int Map[MAX]; //状态图 9 int fac[8] = { 1,1,2,6,24,120,720,5040}; 10 struct Board{ 11 int fa; //记录上一状态 12 int val; //Hash值 13 char str[9]; 14 void Contor(); 15 }m[2*MAX],ts; 16 void Board::Contor() 17 { 18 int num = 0; 19 for (int i = 0; i < 8; i++) 20 { 21 int tmp = 0; 22 for (int j = i + 1; j < 8; j++) 23 { 24 if (this->str[j] < this->str[i]) tmp++; 25 } 26 num += tmp*fac[7 - i]; 27 } 28 this->val = num; 29 } 30 void Init(char s[9]) 31 { 32 int rear = 0; 33 int tail = 1; 34 strcpy(m[0].str, s); 35 m[0].Contor(); 36 while (rear < tail) { 37 if (Map[m[rear].val]) 38 { 39 rear++; 40 continue; 41 } 42 Map[m[rear].val] = Map[m[m[rear].fa].val] + 1; 43 /*由于是反向搜索,因此将逆向操作即可*/ 44 // 交换行 45 for (int i = 0; i < 8; i++) 46 m[tail].str[(i + 4) % 8] = m[rear].str[i]; 47 m[tail].Contor(); 48 if (!Map[m[tail].val]) { 49 m[tail].fa = rear; 50 tail++; 51 } 52 // 循环左移 53 for (int i = 0; i < 4; i++) 54 m[tail].str[(i + 3) % 4] = m[rear].str[i]; 55 for (int i = 4; i < 8; i++) 56 m[tail].str[(i + 3) % 4 + 4] = m[rear].str[i]; 57 m[tail].Contor(); 58 if (!Map[m[tail].val]) { 59 m[tail].fa = rear; 60 tail++; 61 } 62 // 中心逆旋转 63 strcpy(m[tail].str, m[rear].str); 64 m[tail].str[5] = m[rear].str[1]; m[tail].str[1] = m[rear].str[2]; 65 m[tail].str[2] = m[rear].str[6]; m[tail].str[6] = m[rear].str[5]; 66 m[tail].Contor(); 67 if (!Map[m[tail].val]) { 68 m[tail].fa = rear; 69 tail++; 70 } 71 rear++; 72 } 73 } 74 int main() 75 { 76 /*预处理*/ 77 Init("12348765"); 78 int T; 79 scanf("%d", &T); 80 while (T--) 81 { 82 int tmp; 83 for (int i = 0; i < 4; i++) 84 { 85 scanf("%d", &tmp); 86 ts.str[i] = tmp + '0'; 87 } 88 for (int i = 4; i < 8; i++) 89 { 90 scanf("%d", &tmp); 91 ts.str[(8 - i) + 3] = tmp + '0'; 92 } 93 ts.Contor(); 94 printf("%d ", Map[ts.val] - 1); 95 } 96 return 0; 97 }