八數碼(有一個空的移動拼圖模型)
阿新 • • 發佈:2018-12-15
Problem J
八數碼
時限:5000ms 記憶體限制:20000K 總時限:10000ms
描述:
在九宮格里放在1到8共8個數字還有一個是空格,與空格相鄰的數字可以移動到空格的位置,問給定的狀態最少需要幾步能到達目標狀態(用0表示空格): 1 2 3 4 5 6 7 8 0
輸入:
輸入一個給定的狀態。
輸出:
輸出到達目標狀態的最小步數。不能到達時輸出-1。
輸入樣例:
1 2 3 4 0 6 7 5 8
輸出樣例:
2
來源:
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<map> #include<cmath> using namespace std; queue<int> q; map<int,int> si; int a[10],b[10]; int power(int u,int p) { int ans=1; if(p==0) return 1; else { for(int i=1;i<=p;i++) ans*=u; } return ans; } int trans(int num,int flag) { int i=8; int temp; int r,c; memset(a,0,sizeof(a));//0要重置0,因為首位可能是0,數值就沒有8位,a[8]的值無法判斷 while(num!=0) { int temp=power(10,i); a[i]=num/temp; num%=temp; i--; } for(i=8;i>=0;i--) { int row=(8-i)/3; int col=(8-i)%3; if(a[i]==0) { r=row; c=col; temp=i; break; } } if(flag==1) { if(r>=1) { a[temp]=a[temp+3]; a[temp+3]=0; for(i=8;i>=0;i--) num+=a[i]*power(10,i); } } else if(flag==2) { if(r<=1) { a[temp]=a[temp-3]; a[temp-3]=0; for(i=8;i>=0;i--) num+=a[i]*power(10,i); } } else if(flag==3) { if(c>=1) { a[temp]=a[temp+1]; a[temp+1]=0; for(i=8;i>=0;i--) num+=a[i]*power(10,i); } } else if(flag==4) { if(c<=1) { a[temp]=a[temp-1]; a[temp-1]=0; for(i=8;i>=0;i--) num+=a[i]*power(10,i); } } return num; } int numxxx; void bfs() { int num; int flag; int temp; while(!q.empty()) { num=q.front(); q.pop(); if(num==123456780) { printf("%d\n",si[123456780]-1); return;} else { for(flag=1;flag<=4;flag++) { temp=trans(num,flag); if(temp!=0) { if(si.count(temp)==0) { si[temp]=si[num]+1; q.push(temp); } } } } } printf("-1\n"); } int main() { int temp; int i; scanf("%d",&temp); numxxx=temp*power(10,8); for(i=7;i>=0;i--) { scanf("%d",&temp); numxxx+=temp*power(10,i); } si[numxxx]=1; q.push(numxxx); bfs(); }