分析:
简单的bfs,但要注意因为输入cases很多,对每个初始状态都搜一遍会超时,其实可以从终止状态反向搜一遍,对搜到的每个状态打表存下即可。
代码:
//poj 3221
//sep9
#include <iostream>
#include <queue>
using namespace std;
int n;
int fac[]={1,1,2,6,24,120,720,5040,40320};
int vis[10000],g[10000];
int pos[8][8];
struct NODE
{
int s[9];
int loc;
int status;
};
int cantor(int s[])
{
int sum=0;
for(int i=0;i<7;++i){
int cnt=0;
for(int j=i+1;j<7;++j)
if(s[i]>s[j])
++cnt;
sum+=cnt*fac[7-i-1];
}
return sum;
}
void bfs(NODE start)
{
queue<NODE> open;
NODE cur,nxt;
memset(vis,0,sizeof(vis));
memset(g,-1,sizeof(g));
vis[start.status]=1;
g[start.status]=0;
open.push(start);
while(!open.empty()){
cur=open.front();open.pop();
int cur_zero_pos=cur.loc;
for(int i=1;i<=pos[cur_zero_pos][0];++i){
int nxt_zero_pos=pos[cur_zero_pos][i];
nxt=cur;
swap(nxt.s[cur_zero_pos],nxt.s[nxt_zero_pos]);
nxt.loc=nxt_zero_pos;
nxt.status=cantor(nxt.s);
if(vis[nxt.status]==0){
open.push(nxt);
g[nxt.status]=g[cur.status]+1;
vis[nxt.status]=1;
}
}
}
}
int main()
{
int cases;
pos[0][0]=3,pos[0][1]=2,pos[0][2]=4,pos[0][3]=6;
pos[1][0]=2,pos[1][1]=2,pos[1][2]=6;
pos[2][0]=3,pos[2][1]=0,pos[2][2]=1,pos[2][3]=3;
pos[3][0]=2,pos[3][1]=2,pos[3][2]=4;
pos[4][0]=3,pos[4][1]=0,pos[4][2]=3,pos[4][3]=5;
pos[5][0]=2,pos[5][1]=4,pos[5][2]=6;
pos[6][0]=3,pos[6][1]=0,pos[6][2]=1,pos[6][3]=5;
NODE ncur;
for(int i=0;i<7;++i)
ncur.s[i]=i;
ncur.loc=0;
ncur.status=cantor(ncur.s);
bfs(ncur);
scanf("%d",&cases);
while(cases--){
char ch[16];
int s[16];
scanf("%s",ch);
for(int i=0;i<7;++i)
s[i]=ch[i]-'0';
int cantor_value=cantor(s);
printf("%d\n",g[cantor_value]);
}
return 0;
}