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; }