hdu 1430 魔板(康托展开+BFS+巧妙转换)
来源:互联网 发布:反恐精英控制台优化 编辑:程序博客网 时间:2024/05/08 22:38
魔板
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2870 Accepted Submission(s): 634
Problem Description
在魔方风靡全球之后不久,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
给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
1 2 3 4
8 7 6 5
对于魔板,可施加三种不同的操作,具体操作方法如下:
A: 上下两行互换,如上图可变换为状态87654321
B: 每行同时循环右移一格,如上图可变换为41236785
C: 中间4个方块顺时针旋转一格,如上图可变换为17245368
给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
Input
每组测试数据包括两行,分别代表魔板的初态与目态。
Output
对每组测试数据输出满足题意的变换步骤。
Sample Input
12345678172453681234567882754631
Sample Output
CAC
Author
LL
题意:中文题不解释思路:和八数码问题差不多,只不过这个题没有明确的始态和终态,我的第一想法肯定打不了表,于是每次都重新从始态找到终态,自然而然会TLE。
其实这个题是可以打表的,我们先把从12345678这个状态到所有状态的路径都用BFS都保存下来,用康托展开去做hash保存即可
然后把输入跟输出的序列转换一下,比如
输入56412387 输出12348765
那么我们就把输入转换成12345678,于是可以得到一个pos数组为{4,5,6,3,1,2,8,7}
然后我们再把输出序列转换一下,对应可以得到45637821
这个正确性应该是显而易见的
然后就从45637821->12345678找出路径即可
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>using namespace std;struct Node{ char step; int father;} node[45000];struct Node1{ int s[10]; int id;};int num[10],goal[10],f[10],pos[10];char op[1000];void init(){ f[0]=1; for(int i=1; i<=8; i++) f[i]=f[i-1]*i; for(int i=0; i<40500; i++) node[i].father=-1;}int cantor(int *a){ int ans=0; for(int i=1; i<=8; i++) { int k=0; for(int j=i+1; j<=8; j++) if(a[i]>a[j]) k++; ans+=k*f[8-i]; } return ans;}void A(int *a){ swap(a[1],a[5]); swap(a[2],a[6]); swap(a[3],a[7]); swap(a[4],a[8]);}void B(int *a){ swap(a[3],a[4]); swap(a[7],a[8]); swap(a[2],a[3]); swap(a[6],a[7]); swap(a[1],a[2]); swap(a[5],a[6]);}void C(int *a){ swap(a[2],a[3]); swap(a[2],a[7]); swap(a[2],a[6]);}int check(int *a){ for(int i=1; i<=8; i++) if(a[i]!=goal[i]) return 0; return 1;}void bfs(){ queue<Node1>que; Node1 p,next; for(int i=1; i<=8; i++) p.s[i]=i; p.id=0; que.push(p); while(!que.empty()) { Node1 now=que.front(); que.pop(); next=now; A(next.s); next.id=cantor(next.s); if(node[next.id].father==-1) { node[next.id].father=now.id; node[next.id].step='A'; que.push(next); } next=now; B(next.s); next.id=cantor(next.s); if(node[next.id].father==-1) { node[next.id].father=now.id; node[next.id].step='B'; que.push(next); } next=now; C(next.s); next.id=cantor(next.s); if(node[next.id].father==-1) { node[next.id].father=now.id; node[next.id].step='C'; que.push(next); } }}int main(){ char a[10],b[10]; init(); bfs(); while(~scanf("%s %s",a,b)) { for(int i=0; i<strlen(a); i++) num[i+1]=a[i]-'0'; swap(num[5],num[8]); swap(num[6],num[7]); for(int i=1; i<=8; i++) pos[num[i]]=i; for(int i=0; i<strlen(b); i++) goal[i+1]=b[i]-'0'; swap(goal[5],goal[8]); swap(goal[6],goal[7]); for(int i=1; i<=8; i++) goal[i]=pos[goal[i]]; int id=cantor(goal),cnt=0; while(id) { op[++cnt]=node[id].step; id=node[id].father; } for(int i=cnt;i>=1;i--) printf("%c",op[i]); printf("\n"); } return 0;}
0 0
- hdu 1430 魔板(康托展开+BFS+巧妙转换)
- hdu 1430 魔板(bfs+预处理+康托展开)
- HDU 1430 魔板 康托展开或字典树 + BFS
- HDU 1043 Eight(bfs+康托展开)
- hdu 3567 Eight II (bfs+康托展开+预处理)
- HDU Eight II(BFS+康托展开)
- [BFS+康托展开]Hdu 1043 Eight
- hdu 3567 康托展开 +BFS
- hdu1430魔板(BFS+康托展开)
- 【USACO3.2.5】魔板 康托展开/BFS
- loj 1165(bfs+康托展开)
- HDU - 1430 魔板 (bfs预处理 + 康托)
- hdu1430(康托展开+BFS)
- 康托展开+bfs-2
- POJ 1077 Eight & HDU 1043 Eight(康托展开+BFS)
- hdu 1043 /poj 1077 Eight(经典八数码问题,BFS+康托展开)
- hdu 1043/poj 1077 Eight (八数码 经典搜索题 bfs + 康托展开)
- HDU 1043 Eight(反向BFS打表+康托展开)
- Struts2中action用注解的方式配置
- HTC VIVE可以从站立式改成坐式直接使用吗?当然可以。。。
- 语录
- Android Studio的常用快捷键
- 运用TensorFlow处理简单的NLP问题
- hdu 1430 魔板(康托展开+BFS+巧妙转换)
- 第二天(5道)
- 七牛云存储上传文件
- 我总结的设计模式
- Java之线程(接口)
- 运用TensorFlow处理简单的NLP问题
- 家具厂设计拆单+生产数控管理系统
- mailx发送邮件
- [LeetCode]--306. Additive Number