1. 程式人生 > >Luogu P2324 [SCOI2005]騎士精神

Luogu P2324 [SCOI2005]騎士精神

題意

(我也會簡化題意了qwq)

給一個矩陣,有一個空格在其中,每次操作可以按規則將其他格子與這個空格交換,多少次達到目標狀態?
規則:馬在棋盤上跳的規則(當然不存在被堵了馬腳的情況quq)

爆搜嗎,把空格當馬跳,肯定會炸掉的。。。
標籤是啟發式搜尋還有一個神祕的A*演算法
sto向騎(xie)士(e)精(ti)神(mu)低頭。。。我又膜(bu)了(si)題(kao)解(le)
lhy向我推薦的這篇題解還挺好的

importance:

要把當前相差的方格數記錄,努力使相差的方格數減少,還要防止它走回去
#include<cstdio>
#include<cstring>
//01int map[10][10],ans,k,tot,sx,sy; char s1[1010]; int goal[6][6]={0,0,0,0,0,0, 0,1,1,1,1,1, 0,0,1,1,1,1, 0,0,0,2,1,1, 0,0,0,0,0,1, 0,0,0,0,0,0}; int dx[8]={1,1,2,2,-2,-2,-1,-1}; int dy[8]={-2,2,-1,1,-1,1,-2,2}; int dfs(int x,int y,int t,int
sum,int back) { if(t>15)return 0; //if(sum>0) //printf("%d %d %d %d %d\n",x,y,t,sum,back); if(sum==0&&t<=15) { if(t<ans)ans=t; return 0; } for(int i=0;i<8;i++) { if(i+back!=7) { int xx=x+dx[i]; int
yy=y+dy[i]; int fff1=0,fff2=0; if(xx>=1&&yy>=1&&xx<=5&&yy<=5) { int num=sum;fff1=0;fff2=0; if(map[x][y]!=goal[x][y])fff1=1; if(map[xx][yy]!=goal[xx][yy])fff2=1; int b=map[xx][yy];map[xx][yy]=map[x][y];map[x][y]=b; if(map[xx][yy]==goal[xx][yy]) { if(fff2) num--; } else { if(fff2==0) num++; } if(map[x][y]==goal[x][y]) { if(fff1) num--; } else { if(fff1==0) num++; } if(t+1+num<=17) dfs(xx,yy,t+1,num,i); b=map[xx][yy];map[xx][yy]=map[x][y];map[x][y]=b; } } } } int main() { scanf("%d",&k); while(k--) { ans=999999999,tot=0; for(int i=1;i<=5;i++) { scanf("%s",s1+1); for(int j=1;j<=5;j++) { if(s1[j]=='1') { map[i][j]=1; } if(s1[j]=='0') { map[i][j]=0; } if(s1[j]=='*') { sx=i;sy=j; map[i][j]=2; } if(map[i][j]!=goal[i][j])tot++; } }//printf("%d\n",tot); /*for(int i=1;i<=5;i++) { for(int j=1;j<=5;j++) { printf("%d",map[i][j]); }printf("\n"); }*/ dfs(sx,sy,0,tot,-1); //x座標,y座標,步數,相差數,防止返回的玩意兒 if(ans==999999999) { printf("-1\n");continue; } printf("%d\n",ans); } }

因為一直沒看到ans==999999999那裡少打了一個=
所以一直不明白為什麼只輸出-1還多浪費了一箇中午QAQ