魔板问题:
http://acm.hdu.edu.cn/showproblem.php?pid=1430
复习一下康托展开哈希,再次学习一下amb的代码。非常好理解
大神的代码看起来就是美
#include<map>
#include<queue>
#include<string>
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
char smaze[10],tmaze[10];
bool vis[50000];
const int fac[]={1,1,2,6,24,120,720,5040,40320};
int inv_hash(char str[])
{
int ans=0;
for(int i=0;i<8;i++)
{
int cnt=0;
for(int k=i-1;k>=0;k--)
{
if(str[k]>str[i])
cnt++;
}
ans+=fac[i]*cnt;
}
return ans;
}
struct node
{
char str[10];
node(){}
node(char _s[])
{
strncpy(str,_s,10);
}
};
void cvrA(node &n)
{
reverse(n.str,n.str+8);
}
void cvrB(node& n)
{
char tmp;
tmp=n.str[0]; n.str[0]=n.str[3]; n.str[3]=n.str[2];
n.str[2]=n.str[1]; n.str[1]=tmp;
tmp=n.str[4]; n.str[4]=n.str[5]; n.str[5]=n.str[6];
n.str[6]=n.str[7]; n.str[7]=tmp;
}
void cvrC(node& n)
{
char tmp=n.str[1]; n.str[1]=n.str[6]; n.str[6]=n.str[5];
n.str[5]=n.str[2]; n.str[2]=tmp;
}
int pre[50000];
char ctrl[50000];
void bfs()
{
memset(vis,0,sizeof(vis));
queue<node>que;
que.push(node("12345678"));
vis[0]=1;
while(!que.empty())
{
node cur=que.front(); que.pop();
int uh=inv_hash(cur.str);
node tmp(cur);
//3次操作
cvrA(tmp);
int vh=inv_hash(tmp.str);
if(!vis[vh])
{
vis[vh]=1;
pre[vh]=uh;
ctrl[vh]='A';
que.push(tmp);
}
//恢复
tmp=cur;
cvrB(tmp);
vh=inv_hash(tmp.str);
if(!vis[vh])
{
vis[vh]=1;
pre[vh]=uh;
ctrl[vh]='B';
que.push(tmp);
}
//恢复
tmp=cur;
cvrC(tmp);
vh=inv_hash(tmp.str);
if(!vis[vh])
{
vis[vh]=1;
pre[vh]=uh;
ctrl[vh]='C';
que.push(tmp);
}
}
}
char stk[1000];
int pmaze[10];
int main()
{
bfs();
while(~scanf("%s %s",smaze,tmaze))
{
for(int i=0;i<8;i++)
pmaze[smaze[i]-'1']=i;
for(int i=0;i<8;i++)
tmaze[i]=pmaze[tmaze[i]-'1']+'1';
node tn=node(tmaze);
int tmp=inv_hash(tn.str);
int t=0;
while(tmp)
{
stk[t++]=ctrl[tmp];
tmp=pre[tmp];
}
while(t--) putchar(stk[t]);
puts("");
}
return 0;
}