1. 程式人生 > >BZOJ 1085 [SCOI2005]騎士精神

BZOJ 1085 [SCOI2005]騎士精神

sca oid display swa 技術 cstring 技術分享 ont res

據說是A_star的裸題,感覺就是爆搜剪枝。

技術分享
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
int ans,T,x,y;
char a[6][6],b[6][6]={{"11111"}, {"01111"}, {"
00*11"}, {"00001"}, {"00000"}}; int xx[10]={-1,-1,1,1,-2,-2,2,2},yy[10]={-2,2,-2,2,-1,1,1,-1}; int ok(int i,int j) {return i>=0&&i<5&&j>=0&&j<5;} int check(char a[][6],char b[][6]) { int res=0; for(int i=0;i<5;i++) for(int j=0;j<5;j++) if(a[i][j]!=b[i][j]) res++;
return res; } int same(char a[][6],char b[][6]) { int res=0; for(int i=0;i<5;i++) for(int j=0;j<5;j++) if(a[i][j]!=b[i][j]) return 0; return 1; } void dfs(int dep) { if(same(a,b)) { ans=min(ans,dep); return; } if(dep>min(ans,15)) return
; for(int i=0;i<5;i++) for(int j=0;j<5;j++) if(a[i][j]==*) x=i,y=j; for(int i=0;i<8;i++) { x+=xx[i]; y+=yy[i]; if(ok(x,y)){ swap(a[x][y],a[x-xx[i]][y-yy[i]]); if(check(a,b)+dep<=ans) dfs(dep+1); swap(a[x][y],a[x-xx[i]][y-yy[i]]); } x-=xx[i]; y-=yy[i]; } } int main() { scanf("%d",&T); while(T--) { for(int i=0;i<5;i++) scanf("%s",a[i]); ans=16; dfs(0); if(ans==16) printf("-1\n"); else printf("%d\n",ans); } return 0; }
View Code

BZOJ 1085 [SCOI2005]騎士精神