SWUN 1425 – 瘋狂的馬兒

來源:互聯網
上載者:User

 

瘋狂的馬兒 時間限制(普通/Java) : 1000 MS/ 3000 MS          運行記憶體限制 : 65536 KByte
總提交 : 19            測試通過 : 5

描述

在一個5*5規模的棋盤上,放著黑馬和白馬。每種馬都有12個,因此棋盤上恰好有一個空格。在任意時刻,馬兒只允許移動到空格上(移動規則如所示)

 

現在,給定棋盤的初始狀態,Snow_storm想知道最少移動幾次可以達到如所示的目標狀態:

 

輸入

     輸入的第一行為正整數T(<=100),表示測試組數。

 

     對於每組測試資料,共有5行,每行有5個字元,表示棋盤的初始狀態:其中’0’表示白馬,’1’表示黑馬,’ ’表示空格。

 

     其中範例一對應的狀態如所示:

輸出

    對於每組測試資料,若不能在16步之內(<16)達到目標狀態,則輸出Crazy horse,否則輸出最小步數。更多的細節請參看範例輸出。

範例輸入

2
01011
110 1
01110
01010
00100
10110
01 11
10111
01001
00000

範例輸出

Case 1: Crazy horse
Case 2: 7

題目來源

YB

 

題目地址:

http://218.194.91.48/acmhome/problemdetail.do?&method=showdetail&id=1425

原題:http://www.lightoj.com  題號1143  。。。 PS: 此題在輸出時對原題做了改動。

===================================================================================================

 

 

其實只要有想法,這題的代碼還是比較好實現的。

 

初步寫的時候,就是用B哥說的,KM匹配作為啟發學習法,寫IDA*。

 

KM匹配只看了一點。所以讓怪叔叔代敲(直接套B哥的模版)。。。

 

匹配的建圖自己建,一開始對於每次匹配都重新BFS一次建圖。。。

 

結果TLE在第一組測試資料。。。 於是預先處理所有位置到任意位置的步數,此時匹配的建圖時間就只有O(5*5*12)。。。

 

再次TLE在第二組測試資料。。。

 

一開始想了個剪枝: 不走回頭路。當你往前走時,記住此時走的方向,當你在下一個位置,判斷一下,不走反方向。。。

 

但是仍然TLE在第二組,貌似剪枝沒效果。。。

 

只能選項組,判斷重複狀態了。。。    不懂B哥選項組的方法(貌似與後向星有關?)

 

想了一下,突然想到用字典樹。。。囧。。。 時間夠了,範例卻過不去,13步能走的,走了15步。。。

 

然後想了一下,找到了一個BUG: DFS是深搜,也就是這個方向第5步產生的狀態,也許另一個方向只需要3步就能產生。。。

 

所以狀態判斷不能只判斷是否曾走過,還要判步數少的能再次走。。。

 

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;char p[6][6];// dfs時的當前地圖 // KM匹配 ===================================const int maxn=33;const int inf=0x3fffffff;int tol,n,m,mat[maxn],lx[maxn],ly[maxn],lack,map[maxn][maxn];bool visx[maxn],visy[maxn];bool Find(int x){    int i,v,y;    visx[x]=true;    for(i=1;i<=n;i++){        y=i;        if(!visy[y]){            int t=lx[x]+ly[y]-map[x][y];            if(!t){                visy[y]=true;                if(mat[y]==-1||Find(mat[y])){                    mat[y]=x;                    return true;                }            }            else if(lack>t) lack=t;        }    }    return false;}int KM(){    int i,j,x,y;    /*// 輸出當前地圖,與構圖結果 cout<<"p------"<<endl;for(i=0;i<5;i++){puts(p[i]);}cout<<"map------"<<endl;for(i=1;i<=n;i++){for(j=1;j<=m;j++)cout<<map[i][j]<<" ";cout<<endl;}*/    memset(mat,-1,sizeof(mat));    for(i=1;i<=n;i++){        lx[i]=-inf;        ly[i]=0;        for(j=1;j<=n;j++){            x=map[i][j];            if(x>lx[i]) lx[i]=x;        }    }    for(i=1;i<=n;i++){        while(1){            memset(visx,false,sizeof(visx));            memset(visy,false,sizeof(visy));            lack=inf;                if(Find(i)) break;                        for(j=1;j<=n;j++){                if(visx[j]) lx[j]-=lack;                if(visy[j]) ly[j]+=lack;            }        }    }    int ret=0;    for(i=1;i<=n;i++){        if(mat[i]!=-1)            ret+=lx[mat[i]],ret+=ly[i];    }    return ret;}// 構圖(用於KM匹配) ============ int fx[]={-2,2,-2,2,1,-1,1,-1};int fy[]={-1,1,1,-1,2,-2,-2,2};int d1[5][5]={{1,2,3,4,5},{0,6,7,8,9},{0,0,0,10,11},{0,0,0,0,12},{0,0,0,0,0}};int d2[5][5]={{0,0,0,0,0},{12,0,0,0,0},{10,11,0,0,0},{6,7,8,9,0},{1,2,3,4,5}};int rec[6][6][6][6];struct Node{int x,y;Node(){}Node(int a,int b){x=a,y=b;}}que[20000];void deal(){// 預先處理任意座標(x1,y1)到任意座標(x2,y2)之間的最短步數 int i,j,vis[6][6],ss,st,cnt=1,nx,ny,k,tx,ty;for(i=0;i<5;i++)for(j=0;j<5;j++){memset(vis,-1,sizeof(vis));que[ss=st=0]=Node(i,j);vis[i][j]=0;while(ss<=st){nx=que[ss].x;ny=que[ss].y;ss++;if(d1[nx][ny]!=0)rec[i][j][nx][ny]=-vis[nx][ny];if(d2[nx][ny]!=0)rec[i][j][nx][ny]=-vis[nx][ny];for(k=0;k<8;k++){tx=nx+fx[k];ty=ny+fy[k];if(tx<0 || ty<0 || tx>4 || ty>4) continue;if(vis[tx][ty]!=-1) continue;vis[tx][ty]=vis[nx][ny]+1;st++;que[st].x=tx;que[st].y=ty;}}cnt++;}}int BFS1(){// 匹配黑馬 int i,j,g,f,cnt=1;for(i=0;i<5;i++)for(j=0;j<5;j++)if(p[i][j]=='1'){for(g=0;g<5;g++)for(f=(g<2?g:g+1);f<5;f++)map[cnt][d1[g][f]]=rec[i][j][g][f];cnt++;}n=12,m=12;return KM();}int BFS2(){// 匹配白馬 int i,j,g,f,cnt=1;for(i=0;i<5;i++)for(j=0;j<5;j++)if(p[i][j]=='0'){for(g=0;g<5;g++)for(f=(g>2?g:g-1);f>=0;f--)map[cnt][d2[g][f]]=rec[i][j][g][f];cnt++;}n=12,m=12;return KM();}// 字典樹(用於儲存狀態) ================== struct Tree{int step;Tree *next[3];};Tree *root;void init_(Tree *x){// 初始化新節點 x->step=10000;x->next[0]=x->next[1]=x->next[2]=0;}int cover(int step){// 加入字典樹 Tree *new_,*now=root;int i,j,k,flag=0;for(i=0;i<5;i++)for(j=0;j<5;j++){if(p[i][j]=='0') k=0;else if(p[i][j]=='1') k=1;else k=2;if(now->next[k]==0){new_=new Tree;init_(new_);now->next[k]=new_;}now=now->next[k];}if(now->step>step){// 判斷可否再走 now->step=step;flag=1;}return flag;}void clr(Tree *x){// 刪除字典樹 (釋放記憶體) if(x->next[0]) clr(x->next[0]);if(x->next[1]) clr(x->next[1]);if(x->next[2]) clr(x->next[2]);delete x;}//  啟發學習法搜尋 ============= bool dfs(int x,int y,int step,int tol){int k,h,nx,ny;h=-(BFS1()+BFS2());// 啟發學習法 if(h==0) return true;if(h+step>tol) return false;for(k=0;k<8;k++){nx=x+fx[k];ny=y+fy[k];if(nx<0 || ny<0 || nx>4 || ny>4) continue;swap(p[nx][ny],p[x][y]);if(cover(step+1))// 查詢此狀態是否曾走過 if(dfs(nx,ny,step+1,tol)) return true;swap(p[nx][ny],p[x][y]);}return false;}//  主函數 =============== int main(){int tt,t,si,sj,i,j;bool res;char mp[6][6];deal();scanf("%d",&t);getchar();for(tt=1;tt<=t;tt++){for(i=0;i<5;i++){gets(mp[i]);memcpy(p[i],mp[i],5);for(j=0;j<5;j++)if(mp[i][j]==' ')si=i,sj=j;}i=BFS1()+BFS2();if(i<16)for(i=0;i<16;i++){// DIA*for(j=0;j<5;j++)memcpy(p[j],mp[j],5);root=new Tree;// 建立字典樹 init_(root);cover(0);res=dfs(si,sj,0,i);clr(root);if(res) break;}printf("Case %d: ",tt);if(i<16) printf("%d\n",i);else puts("Crazy horse");}return 0;}/*100111011111111100 0000000*/

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.