12345678 17245368 12345678 82754631
C AC
题意.。。。
备注:康拓展开其实就是一个返回这个序列在以这个序列中的数形成的全排列中的次序。例如123, 那么它在以123形成的全排列中为第一个康拓返回0; 132 返回1.。。
下面的是为了便于表达,可能表达不是太恰当,请各位大大指教。
分析:用康拓展开来标记已出现的状态。
预处理就是从“12345678”(原始态)开始BFS,记录到达每一个状态的的值,最小字典序不用考虑因为只要是找到了肯定是字典序最小的。
但是给出的初态不一定是原始态,所以我们要置换一下。
置换: 原始态为“12345678” 例如 初态是 “45781236” 目态是 ”78451326“
目态的第一位‘7’ 在初态中是第三位, 而原始态的第三位是‘3’,故目态的第一位应该转换为‘3’,就这样一次转换 最后目态转换为 34125768, 最后找出34125768对应的康拓值,输出就好了。
代码:
#include <cstdio> #include <cstring> #include <string> #include <queue> #include <iostream> const int M = 50000; using namespace std; struct node{ string s, path; int val; }; const int f[] = {1, 1, 2, 6, 24, 120, 720, 5040, 5040*8}; string ans[M]; bool vis[M]; int cal(string s){ //康拓 int sum = 0; for(int i = 0; i < 8; ++ i){ int cnt = 0; for(int j = i+1; j < 8; ++ j) if(s[j] < s[i]) ++cnt; sum += cnt*f[7-i]; } return sum; } string tran(string s, int num){ //转换 //string res = ""; int i; if(num == 0){ for(i = 0; i < 4; ++ i){ swap(s[i], s[i+4]); } } else if(num == 1){ char t= s[3]; for(i = 2; i >= 0; -- i) s[i+1] = s[i]; s[0] = t; t = s[7]; for(i = 6; i >= 4; -- i) s[i+1] = s[i]; s[4] = t; } else{ char t = s[1]; s[1] = s[5]; s[5] = s[6]; s[6] = s[2]; s[2] = t; } return s; } void bfs(string st){ //遍历 memset(vis, 0, sizeof(vis)); queue<node > q; node t; t.s = st; t.val = cal(t.s); t.path = ""; ans[t.val] = t.path; vis[t.val] = 1; q.push(t); while(!q.empty()){ node temp = q.front(); q.pop(); for(int i = 0; i < 3; ++ i){ node cur = temp; cur.path += (i+'A'); string a = tran(cur.s, i); int k = cal(a); if(!vis[k]){ cur.s = a; cur.val = k; ans[cur.val] = cur.path; vis[k] = 1; q.push(cur); } } } } int main(){ string st = "12345678"; bfs(st); string en, ss; int i; while(cin >> ss >> en){ swap(ss[4], ss[7]); //因为我是按照12345678这样来的,而不是按照题意顺时针的,所以要交换 swap(ss[5], ss[6]); swap(en[4], en[7]); swap(en[5], en[6]); string mm(8, 'a'); for(i = 0; i < 8; ++ i) mm[ss[i]-'0'] = i+'1'; //下面的两个for循环就是置换 // ss.clear(); string de; for(i = 0; i < 8; ++ i) de += mm[en[i]-'0']; // cout << de<<endl; int k = cal(de); cout << ans[k]<<endl; } return 0; }
Hdoj 1430 魔板 【BFS】+【康拓展开】+【预处理】
原文地址:http://blog.csdn.net/shengweisong/article/details/45252393