1. 程式人生 > >BZOJ 1085 / LOJ 2151 [SCOI2005]騎士精神 (剪枝/A*迭代搜尋)

BZOJ 1085 / LOJ 2151 [SCOI2005]騎士精神 (剪枝/A*迭代搜尋)

題目大意:略

直接爆搜會T,我們優化一下,統計出當前棋盤和目標棋盤不同的位置的數量k,那麼當前棋盤變成目標棋盤最少的移動次數是k-1

每次選擇一個最大深度ma,那麼如果當前走了dep步,顯然必須保證dep+k-1<=ma,否則當前棋盤就是永遠無法在規定步數ma內到達目標棋盤的

其實這個不算很A*吧...應該算剪枝

移動方向的數量打錯了WA了好久...另外LOJ上有這道題的資料

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5
#define NN 65538 6 #define MM 100 7 #define ll long long 8 #define uint unsigned int 9 #define ull unsigned long long 10 #define inf 0x3f3f3f3f 11 #define idx(X,Y) ((X)*5+(Y)) 12 using namespace std; 13 14 int T; 15 const int Ed=549855; 16 const int maxn=65535; 17 int mp[7][7],bin[30],cnt[NN];
18 int xx[]={-2,-1,1,2,2,1,-1,-2}; 19 int yy[]={1,2,2,1,-1,-2,-2,-1}; 20 int check(int x,int y) 21 {if(x<0||y<0||x>4||y>4)return 0;return 1;} 22 int dfs(int dep,int s,int p,int ma,int fa,int fp) 23 { 24 if(s==Ed&&p==12) return 1; 25 if(dep>=ma) return 0; 26 int x=p/5
,y=p%5; 27 int tx,ty,t,tp,sum,h,ans; 28 sum=Ed^s; 29 h=cnt[sum&maxn]+cnt[sum>>16]; 30 if((p!=12)&&(!(sum&(1<<p)))&&(!(Ed&(1<<p)))) h++; 31 if((p!=12)&&(!(sum&(1<<12)))&&(!(s&(1<<12)))) h++; 32 if(dep+h-1>ma) return 0; 33 for(int k=0;k<8;k++) 34 { 35 tx=x+xx[k],ty=y+yy[k]; 36 if(!check(tx,ty)) continue; 37 if(s&(bin[idx(tx,ty)])) 38 t=(s^bin[idx(tx,ty)])|bin[idx(x,y)]; 39 else t=s; 40 tp=idx(tx,ty); 41 if(t==fa&&tp==fp) continue; 42 ans=dfs(dep+1,t,tp,ma,s,p); 43 if(ans) return 1; 44 }return 0; 45 } 46 47 int main() 48 { 49 //freopen("t2.in","r",stdin); 50 scanf("%d",&T); 51 bin[0]=1; 52 for(int i=1;i<=25;i++) 53 bin[i]=bin[i-1]<<1; 54 for(int i=0;i<65536;i++) 55 for(int j=0;j<16;j++) 56 if(i&(1<<j)) cnt[i]++; 57 while(T--) 58 { 59 char str[10];int s=0,p; 60 for(int i=0;i<5;i++) 61 { 62 scanf("%s",str); 63 for(int j=0;j<5;j++){ 64 if(str[j]=='*'){ 65 p=idx(i,j); 66 }else if(str[j]=='1'){ 67 s|=(bin[idx(i,j)]); 68 } 69 } 70 } 71 int fl=0; 72 for(int k=0;k<=15;k++){ 73 int ans=dfs(0,s,p,k,-1,0); 74 if(ans){ 75 printf("%d\n",k); 76 fl=1;break;} 77 } 78 if(!fl) printf("-1\n"); 79 } 80 return 0; 81 }