第一点:
模板操作是对于8个字母进行操作的,直接处理起来特别麻烦。对于这种有顺序要求的不重复分字符串处理,我们可以考虑康托展开,用一个数字来替代整个字符串。
康拓展开:http://blog.csdn.net/zhongkeli/article/details/6966805
其实就是按照事先的约定,把一个字符串变成一个数字。
第二点:
为了省时间,我们进行预处理,我们需要固定初始值不变,之后枚举它到其他所有状态的变化过程。但是题目给出的初始值不是固定的,所以我们要进行映射。
我们预处理就固定ABCDEFGH这个序列到其他序列的变化了。那么我们需要对所有输入进行处理,变成ABCDEFGH
假设输入为 EFGHABCD 要求变成HABCDEFG
对于第一个E,我们要让他变为A,相应的输出列中的E也要变成A。也就是AFGHABCD/ HABCDAEFG
最后变完ABCDEFGH DEFGHABC
按照预处理的,我们直接输出ans【“DEFGHABC”】即可,当然这个DEFGHABC也要康拓成一个数。
第三点:
就是BFS了,对于一个String,进行三种不同的操作,之后检查操作完的String的康拓数的vis是否访问过,没有求更新,就是普通的BFS了。
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
#define eps 1e-8
#define INF 1e8
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int MOD = 2333333;
const int maxn = 50000 + 5;
int vis[maxn];
string ans[maxn];
int fac[]={1 , 1 , 2 , 6 , 24 , 120 , 720 , 5040 , 40320};
int Cantor(string str)
{
int ret = 0;
int n = str.size();
for(int i = 0 ; i < n ; i++) {
int cnt = 0;
for(int j = i ; j < n ; j++)
if(str[j] < str[i])
cnt++;
ret += cnt * fac[n - i - 1];
}
return ret;
}
void move_A(string &str)
{
for(int i = 0 ; i < 4 ; i++)
swap(str[i] , str[7 - i]);
}
void move_B(string &str)
{
for(int i = 3 ; i > 0 ; i--)
swap(str[i] , str[i - 1]);
for(int i = 4 ; i < 7 ; i++)
swap(str[i] , str[i + 1]);
}
void move_C(string &str)
{
char tmp = str[6];
str[6] = str[5];
str[5] = str[2];
str[2] = str[1];
str[1] = tmp;
}
void BFS(string str)
{
memset(vis , 0 , sizeof(vis));
queue <string> que;
que.push(str);
int x = Cantor(str);
vis[x] = 1;
ans[x] = "";
while(!que.empty()) {
string u = que.front();
que.pop();
int i = Cantor(u);
string tmp = u;
move_A(tmp);
int k = Cantor(tmp);
if(!vis[k]) {
vis[k] = 1;
que.push(tmp);
ans[k] = ans[i] + 'A';
}
tmp = u;
move_B(tmp);
k = Cantor(tmp);
if(!vis[k]) {
vis[k] = 1;
que.push(tmp);
ans[k] = ans[i] + 'B';
}
tmp = u;
move_C(tmp);
k = Cantor(tmp);
if(!vis[k]) {
vis[k] = 1;
que.push(tmp);
ans[k] = ans[i] + 'C';
}
}
}
int main()
{
int a[10];
string s , e;
string start = ("12345678");
BFS(start);
while(cin >> s >> e)
{
for(int i = 0 ; i < 8 ; i++)
a[s[i] - '0'] = i + 1;
for(int i = 0 ; i < 8 ; i++)
e[i] = a[e[i] - '0'] + '0';
int k = Cantor(e);
cout << ans[k] << endl;
}
return 0;
}