赛前做做题,这个题以前好像做过类似的题的感觉。其实就是BFS,做好去重就好了。我这里去重的方法采用的是康托展开式,顺便复习了下
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int maxn=1e6+1000;
struct Node
{
int val;
int ans;
};
int cos[11]={1,1,2,6,24,120,720,5040,40320,362880};
int st,goal;
queue<Node> q;
bool vis[maxn*4];
int SetKang(char *str)
{
int ans=0;
bool use[10];
memset(use,0,sizeof(use));
for(int i=0;i<9;i++)
{
int val=str[i]-'0',cnt=0;
for(int j=1;j<val;j++)
if(!use[j])
cnt++;
ans+=cnt*cos[8-i];
use[val]=1;
}
return ans+1;
}
void GetKang(int val,char *str)
{
val--;
bool use[10];
memset(use,0,sizeof(use));
for(int i=0;i<9;i++)
{
int num=val/cos[8-i],cnt=0;
val=val%cos[8-i];
val=max(0,val);
for(int j=1;j<=9;j++)
if(!use[j])
if(++cnt==num+1)
{
str[i]=j+'0';
use[j]=1;
break;
}
}
str[9]='\0';
}
void Deal(char *str)
{
for(int i=0;i<strlen(str);i++)
if(str[i]=='.')
str[i]='9';
}
int BFS()
{
while(!q.empty())
q.pop();
memset(vis,0,sizeof(vis));
Node node;
node.val=st;
node.ans=0;
q.push(node);
vis[st]=1;
while(!q.empty())
{
Node p=q.front();
q.pop();
char str[11];
GetKang(p.val,str);
int index;
for(int i=0;i<strlen(str);i++)
if(str[i]=='9')
{
index=i;
break;
}
if(index%3>0)
{
swap(str[index],str[index-1]);
int val=SetKang(str);
if(val==goal)
return p.ans+1;
if(!vis[val])
{
node.val=val;
node.ans=p.ans+1;
q.push(node);
vis[val]=1;
}
swap(str[index],str[index-1]);
}
if(index%3<2)
{
swap(str[index],str[index+1]);
int val=SetKang(str);
if(val==goal)
return p.ans+1;
if(!vis[val])
{
node.val=val;
node.ans=p.ans+1;
q.push(node);
vis[val]=1;
}
swap(str[index],str[index+1]);
}
if(index/3>0)
{
swap(str[index],str[index-3]);
int val=SetKang(str);
if(val==goal)
return p.ans+1;
if(!vis[val])
{
node.val=val;
node.ans=p.ans+1;
q.push(node);
vis[val]=1;
}
swap(str[index],str[index-3]);
}
if(index/3<2)
{
swap(str[index],str[index+3]);
int val=SetKang(str);
if(val==goal)
return p.ans+1;
if(!vis[val])
{
node.val=val;
node.ans=p.ans+1;
q.push(node);
vis[val]=1;
}
swap(str[index],str[index+3]);
}
}
return -1;
}
int main()
{
char str[11],end[11];
while(scanf("%s",str)!=EOF)
{
scanf("%s",end);
Deal(str);
Deal(end);
st=SetKang(str);
goal=SetKang(end);
printf("%d\n",BFS());
}
return 0;
}