UESTC 485 Game(康托,BFS)
Today I want to introduce an interesting game to you. Like eight puzzle, it is a square board with 



Now the question is to calculate the minimum steps required from the initial configuration to the final configuration. Note that the initial configuration is filled with a permutation of 

* (which can be any number).
Input
The first line of input contains an integer 






There are 
Output
For every test case, you should output Case #k: first, where 

No Solution! (without quotes).
Sample Input
2
1 2 3
4 5 6
7 8 9
1 2 3
4 5 6
7 9 8
1 2 3
4 5 6
7 8 9
8 * 9
5 3 7
2 * *
Sample Output
Case #1: No Solution!
Case #2: 7
康托展开总结:
http://blog.csdn.net/dacc123/article/details/50952079
利用康托展开
把所有状态bfs一次,
然后再去做
利用康托展开进行bfs预处理。题目给的一个起始的九宫格,和一个目标的九宫格。 不能直接用目标的九宫格去找起始的九宫格,会超时,应该根据把起始九宫格当作
1 2 3
4 5 6
7 8 9
然后确定目标九宫格是怎么样的,这样就可以直接用之前打的表了。预处理就是处理1 2 3 4 5 6 7 8 9到每种九宫格的步数
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <queue>
using namespace std;
struct Node
{
int a[5][5];
int sta;
};
queue<Node> q;
int b[10];
int fac[10];
int vis[400000];
int pre[400000];
int ans;
int f1[10];
int f2[10];
int tran[10];
char ch[10];
bool used[10];
Node cyk;
void facfun()
{
fac[0]=1;
for(int i=1;i<=9;i++)
{
fac[i]=i*fac[i-1];
}
}
int kt(Node q)
{
int cnt=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
b[++cnt]=q.a[i][j];
int sum=0,num=0;
for(int i=1;i<=9;i++)
{
num=0;
for(int j=i+1;j<=9;j++)
{
if(b[i]>b[j])
num++;
}
sum+=num*fac[9-i];
}
return sum;
}
void bfs(Node t)
{
q.push(t);
vis[t.sta]=1;
pre[t.sta]=0;
while(!q.empty())
{
Node term=q.front();
q.pop();
for(int i=1;i<=12;i++)
{
Node temp=term;
if(i<=3)
{
temp.a[i][1]=term.a[i][3];
temp.a[i][2]=term.a[i][1];
temp.a[i][3]=term.a[i][2];
}
else if(i>3&&i<=6)
{
temp.a[i-3][1]=term.a[i-3][2];
temp.a[i-3][2]=term.a[i-3][3];
temp.a[i-3][3]=term.a[i-3][1];
}
else if(i>6&&i<=9)
{
temp.a[1][i-6]=term.a[3][i-6];
temp.a[2][i-6]=term.a[1][i-6];
temp.a[3][i-6]=term.a[2][i-6];
}
else if(i>9&&i<=12)
{
temp.a[1][i-9]=term.a[2][i-9];
temp.a[2][i-9]=term.a[3][i-9];
temp.a[3][i-9]=term.a[1][i-9];
}
int state=kt(temp);
if(vis[state])
continue;
temp.sta=state;
vis[state]=1;
pre[state]=pre[term.sta]+1;
q.push(temp);
}
}
}
void init()
{
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
facfun();
Node st;int cnt=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
st.a[i][j]=++cnt;
st.sta=0;
bfs(st);
}
int anspos;
void dfs(int i)
{
if(i==10)
{
/*for(int p=1;p<=3;p++)
{
for(int k=1;k<=3;k++)
{
cout<<cyk.a[p][k]<<" ";
}
cout<<endl;
}*/
int c=pre[kt(cyk)];
if(c==-1) return;
ans=min(ans,c);return;
}
if(f2[i]==0)
{
for(int j=1;j<=9;j++)
{
if(!used[j])
{
used[j]=true;
int y=i%3,x;
if(y==0){x=i/3;y=3;}
else {x=i/3+1;}
cyk.a[x][y]=j;
dfs(i+1);
used[j]=false;
}
}
}
else
{
int y=i%3,x;
if(y==0){x=i/3;y=3;}
else {x=i/3+1;}
cyk.a[x][y]=f2[i];
dfs(i+1);
}
}
int main()
{
int t;
scanf("%d",&t);
init();
int cas=0;
while(t--)
{
memset(used,0,sizeof(used));
for(int i=1;i<=9;i++)
{
scanf("%d",&f1[i]);
tran[f1[i]]=i;
}
for(int i=1;i<=9;i++)
{
scanf("%s",ch);
f2[i]=ch[0]-'0';
if(f2[i]>=1&&f2[i]<=9)
f2[i]=tran[f2[i]],used[f2[i]]=true;
else
f2[i]=0;
}
ans=1000000;
dfs(1);
if(ans>=1000000)
printf("Case #%d: No Solution!\n",++cas);
else
printf("Case #%d: %d\n",++cas,ans);
}
return 0;
}
浙公网安备 33010602011771号