魔板【HDU-1430】【康托展开+BFS】
2019-08-06 14:55
405 查看
题目链接
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
给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
Input
每组测试数据包括两行,分别代表魔板的初态与目态。
Output
对每组测试数据输出满足题意的变换步骤。
Sample Input
12345678 17245368 12345678 82754631
Sample Output
C AC
被字符串string的不可以直接赋值给卡了一整个上午,debug了半天,其实第一发就该过了,但是这样也好,来来回回写了好几遍,倒是把康托展开给写熟悉了。康托展开就是个由排列组合到一个数的映射,其实就像哈希一样,还是很好理解的。这道题有个关键点,就是在于怎么样去避免TLE。不妨就是把初始字符串等效成“12345678”然后目标字符串去被一一对应即可。
[code]#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 #define INF 0x3f3f3f3f #define HalF (l + r)>>1 #define lsn rt<<1 #define rsn rt<<1|1 #define Lson lsn, l, mid #define Rson rsn, mid+1, r #define QL Lson, ql, qr #define QR Rson, ql, qr #define myself rt, l, r #define MP(x, y) make_pair(x, y) using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 40400; int jc[10]; string ans[maxN]; bool vis[maxN]; inline int Cantor(int len, string a) //康托展开 { int tmp, sum = 0; for(int i=0; i<len; i++) { tmp = 0; for(int j=i+1; j<len; j++) { if(a[i] > a[j]) tmp++; } sum += tmp * jc[len - i - 1]; } return sum + 1; //排名+1 } inline void bfs() { queue<string> Q; string now = "12345678", nex = ""; Q.push(now); int sta = Cantor(8, now), las; vis[sta] = true; ans[sta] = ""; while(!Q.empty()) { now = Q.front(); Q.pop(); nex = now; sta = Cantor(8, now); reverse(nex.begin(), nex.end()); las = Cantor(8, nex); if(!vis[las]) { vis[las] = true; Q.push(nex); ans[las] = ans[sta] + 'A'; } nex = now; char tmp = nex[3]; nex[3] = nex[2]; nex[2] = nex[1]; nex[1] = nex[0]; nex[0] = tmp; tmp = nex[4]; nex[4] = nex[5]; nex[5] = nex[6]; nex[6] = nex[7]; nex[7] = tmp; las = Cantor(8, nex); if(!vis[las]) { vis[las] = true; Q.push(nex); ans[las] = ans[sta] + 'B'; } nex = now; tmp = nex[1]; nex[1] = nex[6]; nex[6] = nex[5]; nex[5] = nex[2]; nex[2] = tmp; las = Cantor(8, nex); if(!vis[las]) { vis[las] = true; Q.push(nex); ans[las] = ans[sta] + 'C'; } } } int F[10]; string A, B; int main() { // freopen("cowjog.in", "r", stdin); // freopen("cowjog.out", "w", stdout); jc[0] = jc[1] = 1; for(int i=2; i<=8; i++) jc[i] = jc[i-1] * i; memset(vis, false, sizeof(vis)); bfs(); while(cin>>A>>B) { for(int i=0; i<8; i++) F[A[i] - '0'] = i + 1; for(int i=0; i<8; i++) B[i] = F[B[i] - '0'] + '0'; cout<<ans[Cantor(8, B)]<<endl; } return 0; } /* 63728145 86372541 ACBBBCBBCBCBCABB */
相关文章推荐
- ACM-康托展开+预处理BFS之魔板——hdu1430
- HDU 1430 魔板 康托展开或字典树 + BFS
- hdu 1430 魔板(bfs+预处理+康托展开)
- hdu1430 魔板(康拓展开 bfs预处理)
- HDU_1430——魔板,预处理,康托展开,置换,string类的+操作
- HDU 1430 魔板 (BFS)
- HDU - 1430 魔板 (bfs预处理 + 康托)
- HDOJ 1430 魔板 (bfs+映射)
- HDU 1430 魔板
- ACM-康托展开+预处理BFS之魔板——hdu1430
- HDU 1430 魔板 搜索
- hdu 1430 魔板 (BFS+预处理)
- HDU 1430 魔板 [BFS+康拓展开]【数学】
- hdu 1430 魔板
- HDU - 1430(BFS)
- hdu 1430 魔板
- HDU 1430 魔板(BFS+HASH+置换)
- HDU 1430 DFS + 康托展开 + 映射处理 +预处理!
- hdu 1430 魔板
- HDU1430,魔板