[SCOI2005]骑士精神
这是一道非常好的,A*模板题。。。
主要思路是通过理想最优情况剪枝。。。
呆码:
#include<iostream> #include<cstdio> using namespace std; int n=5,ans,T,X,Y; char ch[11][11]; char check[6][6]={ '0','0','0','0','0','0', '0','1','1','1','1','1', '0','0','1','1','1','1', '0','0','0','*','1','1', '0','0','0','0','0','1', '0','0','0','0','0','0', }; int lx[9]={0,-2,-2,-1,-1,1,1,2,2}; int ly[9]={0,-1,1,-2,2,-2,2,-1,1}; inline int best() { int tot=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(ch[i][j]!=check[i][j]) tot++; return tot; } inline void dfs(int x,int y,int st,int last) { int l=best(); if(st+l>16) return; if(st>=ans) return; if(l==0) { ans=st; return; } for(int i=1;i<=8;i++) { int xx=x+lx[i]; int yy=y+ly[i]; if(xx<1 || xx>5 || yy<1 || yy>5) continue; if(i+last!=9) { swap(ch[xx][yy],ch[x][y]); dfs(xx,yy,st+1,i); swap(ch[xx][yy],ch[x][y]); } } } int main() { scanf("%d",&T); while(T--) { for(int i=1;i<=n;i++) scanf("%s",ch[i]+1); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(ch[i][j]=='*') X=i,Y=j; ans=17; dfs(X,Y,0,0); printf("%d\n",ans==17 ? -1 : ans); } }