2018.10.2模擬賽

  1. 八數碼
    1 問題描述
    有33 共9 個格子,其中有一個格子是空的,其他格子填滿了18 之間不同的數字。通過
    移動格子可以改變數字和空格的位置,現在給你初狀態和末狀態,請你給出最少的移動步數。
    2 輸入格式
    輸入文件名爲 eight. in。
    給出6 行,每行有3 個數,每兩個數用一個空格空開,每個數在08 之間,其中0 表示空
    格。
    前3 行表示初始狀態,後3 行表示目標狀態。
    3 輸出格式
    輸出文件名爲eight.out。
    輸出一行一個數,表示從初始狀態移動到目標狀態的最少步數。
    如果無解則輸出􀀀1。
    4 樣例
    見下發/eight/eight.in(out)。
    樣例解釋見下發/eight/eight.jpg。

這道題還是一道挺經典的廣搜,再用點康託展開或者map的判重
具體看代碼

#include<bits/stdc++.h>
using namespace std;
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
int a[500000][4][4],b[4][4],ai,aj,f[400000],o[10],fx[400000],fy[400000],c[10][10],ha;
map<int,bool> mp;
int main()
{
    freopen("eight.in","r",stdin);
	freopen("eight.out","w",stdout); 
	int ss=0;
	for (int i=1; i<=3; i++)
	  for (int j=1; j<=3; j++)
	    {
	      scanf("%d",&a[1][i][j]);
	      ss=ss*10+a[1][i][j];
	      if (a[1][i][j]==0) {ai=i; aj=j;}
	    }//讀入初始狀況,記錄0的位置 
    mp[ss]=true;   
	for (int i=1; i<=3; i++)
	  for (int j=1; j<=3; j++)
	      scanf("%d",&b[i][j]);//終點 
   int h=0,t=1;
   fx[t]=ai,fy[t]=aj;//廣搜,0的位置入隊 
   while (h<=t)
     {
   	    h++;
   	    bool pp;
   	    for (int k=0; k<4; k++)
		   {
		   	  int x=fx[h]+dx[k],y=fy[h]+dy[k];//四個方向拓展 
		   	  if (x<1||y<1||x>3||y>3) continue;
		   	  for (int l=1; l<=3; l++)
		   	    for (int p=1; p<=3; p++)
		   	      c[l][p]=a[h][l][p];//記錄一個數組用來判斷新的這種移動是否合法 
		   	  int u=c[x][y];
		   	  c[x][y]=c[fx[h]][fy[h]];
		   	  c[fx[h]][fy[h]]=u;//移動等於交換0和它相鄰的某個數字 
		   	  int s=0;
		   	  for (int l=1; l<=3; l++)
		   	    for (int p=1; p<=3; p++)
		   	      s=s*10+c[l][p];//把數組壓成十進制 ,容易判重 
			  if (mp[s]==false)//map判重 
		   	    {
		   	    	mp[s]=true;
		   	    	t++;
		   	    	fx[t]=x,fy[t]=y;
		   	    	f[t]=f[h]+1;//記錄移動次數 
		   	    	pp=false;
		   	    	for (int l=1; l<=3; l++)
		   	          for (int p=1; p<=3; p++)
		   	            {
		   	              a[t][l][p]=c[l][p];
		   	              if (a[t][l][p]!=b[l][p]) pp=true;
		   	            }//如果合法那麼就是新狀態,每次和終點比較一下,如果成立就可以 
		   	        if (pp==false) {cout<<f[t]; return 0;}
		   	    }
	       }
     }
    cout<<"-1";
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章