p1199八数码问题
oj上简化的八数码问题,最强的数据仅仅是20步;
根据曼哈顿距离构造启发函数;
主算法:IDA*;(使用方法好像不太对......)
未用位运算优化;
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<ctime> 7 #include<cmath> 8 #include<set> 9 #include<map> 10 #include<queue> 11 #include<algorithm> 12 #include<iomanip> 13 #include<queue> 14 using namespace std; 15 #define FILE "dealing" 16 #define up(i,j,n) for(int i=(j);i<=(n);i++) 17 #define pii pair<int,int> 18 #define LL long long 19 namespace IO{ 20 char buf[1<<15],*fs,*ft; 21 int gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?-1:*fs++;} 22 int read(){ 23 int ch=gc(),f=0,x=0; 24 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=gc();} 25 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();} 26 return f?-x:x; 27 } 28 }using namespace IO; 29 const int maxn=10; 30 char ch[maxn],en[maxn]={'1','2','3','8','0','4','7','6','5'}; 31 int a[3][3]; 32 int p[10][10]={ 33 {0,1,2,1,2,3,2,3,4}, 34 {1,0,1,2,1,2,3,2,3}, 35 {2,1,0,3,2,1,4,3,2}, 36 {1,2,3,0,1,2,1,2,3}, 37 {2,1,2,1,0,1,2,1,2}, 38 {3,2,1,2,1,0,3,2,1}, 39 {2,3,4,1,2,3,0,1,2}, 40 {3,2,3,2,1,2,1,0,1}, 41 {4,3,2,3,2,1,2,1,0} 42 }; 43 int x[10],y[10]; 44 inline int check(int a[][3]){ 45 int ans=0; 46 up(i,1,3)x[a[0][i-1]]=i-1; 47 up(i,4,6)x[a[1][i-4]]=i-1; 48 up(i,7,9)x[a[2][i-7]]=i-1; 49 up(i,0,8)ans+=p[x[i]][y[i]]; 50 return ans; 51 } 52 const int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; 53 bool flag=0; 54 int ans=10000; 55 int MaxH=0; 56 void dfs(int a[][3],int d){ 57 int xx,yy; 58 xx=check(a); 59 if(!xx){flag=1;ans=min(ans,d);return;} 60 if(d+xx>MaxH)return; 61 up(i,0,2)up(j,0,2){ 62 if(a[i][j])continue; 63 up(k,0,3){ 64 xx=i+dx[k],yy=j+dy[k]; 65 if(xx<0||yy<0||xx>2||yy>2)continue; 66 swap(a[xx][yy],a[i][j]); 67 dfs(a,d+1); 68 swap(a[xx][yy],a[i][j]); 69 } 70 } 71 return; 72 } 73 int main(){ 74 freopen(FILE".in","r",stdin); 75 freopen(FILE".out","w",stdout); 76 scanf("%s",ch); 77 up(i,0,8)y[en[i]-'0']=i; 78 up(i,1,3)a[0][i-1]=ch[i-1]-'0';up(i,4,6)a[1][i-4]=ch[i-1]-'0';up(i,7,9)a[2][i-7]=ch[i-1]-'0'; 79 for(int i=2;;i+=2){ 80 MaxH=i; 81 dfs(a,0); 82 if(flag)break; 83 } 84 printf("%d\n",ans); 85 cout<<"The time has passed "<<clock()<<" ms."<<endl; 86 return 0; 87 }