HDU_1430——魔板,预处理,康托展开,置换,string类的+操作
2013-07-25 10:59
453 查看
[align=left]Problem Description[/align]
在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板。魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示。任一时刻魔板的状态可用方块的颜色序列表示:从魔板的左上角开始,按顺时针方向依次写下各方块的颜色代号,所得到的数字序列即可表示此时魔板的状态。例如,序列(1,2,3,4,5,6,7,8)表示魔板状态为:
1 2 3 4 8 7 6 5
对于魔板,可施加三种不同的操作,具体操作方法如下:
A: 上下两行互换,如上图可变换为状态87654321 B: 每行同时循环右移一格,如上图可变换为41236785 C: 中间4个方块顺时针旋转一格,如上图可变换为17245368
给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
[align=left]Input[/align]
每组测试数据包括两行,分别代表魔板的初态与目态。
[align=left]Output[/align]
对每组测试数据输出满足题意的变换步骤。
[align=left]Sample Input[/align]
12345678
17245368
12345678
82754631
[align=left]Sample Output[/align]
C
AC
在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板。魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示。任一时刻魔板的状态可用方块的颜色序列表示:从魔板的左上角开始,按顺时针方向依次写下各方块的颜色代号,所得到的数字序列即可表示此时魔板的状态。例如,序列(1,2,3,4,5,6,7,8)表示魔板状态为:
1 2 3 4 8 7 6 5
对于魔板,可施加三种不同的操作,具体操作方法如下:
A: 上下两行互换,如上图可变换为状态87654321 B: 每行同时循环右移一格,如上图可变换为41236785 C: 中间4个方块顺时针旋转一格,如上图可变换为17245368
给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
[align=left]Input[/align]
每组测试数据包括两行,分别代表魔板的初态与目态。
[align=left]Output[/align]
对每组测试数据输出满足题意的变换步骤。
[align=left]Sample Input[/align]
12345678
17245368
12345678
82754631
[align=left]Sample Output[/align]
C
AC
#include <iostream> #include <string> #include <algorithm> #include <queue> using namespace std; const int MAXN = 40321; //由于此题数字1~8,康托展开的所有情况为8!,共40320种 const int fac[8] = {1,1,2,6,24,120,720,5040}; //康托展开中用到的0~7的阶乘 string ans[MAXN]; //存储各状态的变化步骤,预处理完成 struct node { int a[8]; int n; }u,v; void A(node &t) //A操作 { swap(t.a[0],t.a[7]); swap(t.a[1],t.a[6]); swap(t.a[2],t.a[5]); swap(t.a[3],t.a[4]); } void B(node &t) //B操作 { swap(t.a[3],t.a[2]); swap(t.a[2],t.a[1]); swap(t.a[1],t.a[0]); swap(t.a[4],t.a[5]); swap(t.a[5],t.a[6]); swap(t.a[6],t.a[7]); } void C(node &t) //C操作 { swap(t.a[1],t.a[6]); swap(t.a[6],t.a[5]); swap(t.a[5],t.a[2]); } int contor(node &t) //康托展开 { int tmp, num = 0; for(int i=0; i<8; i++) { tmp = 0; for(int j=i+1; j<8; j++) { if(t.a[j] < t.a[i]) { tmp++; } } num += tmp*fac[7-i]; } return num; } void Init(void) { void (*ptr[3])(node&); //定义函数指针 ptr[0] = A; ptr[1] = B; ptr[2] = C; //指向对应函数方便处理 int mark[MAXN] = {0}; //设置标记 mark[0] = 1; for(int i=0; i<8; i++) //由初始状态12345678开始 { u.a[i] = i+1; } u.n = contor(u); queue<node>que; que.push(u); while(!que.empty()) { u = que.front(); que.pop(); for(int i=0; i<3; i++) //三种变换 { v = u; (*ptr[i])(v); v.n = contor(v); //对副本执行操作并康托展开 if(mark[v.n] == 0) //重复 { char ch = 'A' + i; ans[v.n] = ans[u.n] + ch; //记录步骤 mark[v.n] = 1; //标记 que.push(v); } } } } int main() { Init(); char a[10],b[10]; while(~scanf("%s%s",a,b)) { int n[10]; for(int i=0; i<8; i++) //把初态置换成12345678 { n[a[i] - '0'] = i+1; } for(int i=0; i<8; i++) //把目标状态相对于初态置换 { u.a[i] = n[b[i] - '0']; } cout<<ans[contor(u)]<<endl; //输出由12345678到目标态的步骤 } return 0; }
相关文章推荐
- ACM-康托展开+预处理BFS之魔板——hdu1430
- hdu 1430 魔板(bfs+预处理+康托展开)
- HDU 1430 DFS + 康托展开 + 映射处理 +预处理!
- HDU - 1430 魔板 (bfs预处理 + 康托)
- hdu 1430 魔板 (BFS+预处理)
- HDU 1430 魔板(BFS+HASH+置换)
- HDU 1430 魔板 [BFS+康拓展开]【数学】
- HDU 1430 魔板
- hdu 1430 魔板(康托展开+BFS+巧妙转换)
- hdu 1430+hdu 3567(预处理)
- hdu 1430 魔板
- HDU 1430 魔板
- HDU 1430 魔板 (BFS)
- [HDU 1430] 魔板
- HDU 1430 魔板
- hdu 1430 魔板
- Hdoj 1430 魔板 【BFS】+【康拓展开】+【预处理】
- ACM-康托展开+预处理BFS之魔板——hdu1430
- HDU 1430 魔板
- hdu 1430 魔板 康托展开 + 很好的映射