BZOJ1085: [SCOI2005]骑士精神
生活随笔
收集整理的這篇文章主要介紹了
BZOJ1085: [SCOI2005]骑士精神
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
【傳送門:BZOJ1085】
簡要題意:
有一個5*5的棋盤,棋盤上有12個白棋子,12個黑棋子,和一個空格,每只棋子只能按照馬走日的規(guī)則移動,求出最少步數(shù)達到以下狀態(tài)
題解:
DFS+A*
DFS很容易做,不過時間復(fù)雜度太高
所以用A*來優(yōu)化時間
A*的好處預(yù)判當前遞歸到結(jié)束得到的值,從而判斷是否進入遞歸,部分判斷,避免遍歷太多無用點
參考代碼:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; int a[6][6]; const int dx[9]={0,1,1,-1,-1,2,2,-2,-2}; const int dy[9]={0,2,-2,2,-2,1,-1,1,-1}; bool bk; int ans[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} }; bool pd() {for(int i=1;i<=5;i++) for(int j=1;j<=5;j++) if(a[i][j]!=ans[i][j]) return false;return true; } int w; bool pdA(int k) {int s=0;for(int i=1;i<=5;i++){for(int j=1;j<=5;j++){if(a[i][j]!=ans[i][j]){s++;if(s+k>w) return false;}}}return true; } void dfs(int x,int y,int k) {if(bk==true) return ;if(k==w){if(pd()==true) bk=true;return ;}else{for(int i=1;i<=8;i++){int tx=x+dx[i],ty=y+dy[i];if(tx<1||tx>5||ty<1||ty>5) continue;swap(a[x][y],a[tx][ty]);if(pdA(k)==true) dfs(tx,ty,k+1);swap(a[x][y],a[tx][ty]);}} } int main() {int T;scanf("%d",&T);while(T--){char st[10];int kx,ky;for(int i=1;i<=5;i++){scanf("%s",st+1);for(int j=1;j<=5;j++){if(st[j]=='*'){a[i][j]=2;kx=i,ky=j;}else a[i][j]=st[j]-'0';}}bk=false;for(w=1;w<=15;w++){dfs(kx,ky,0);if(bk==true){printf("%d\n",w);break;}}if(bk==false) printf("-1\n");}return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/Never-mind/p/8608399.html
總結(jié)
以上是生活随笔為你收集整理的BZOJ1085: [SCOI2005]骑士精神的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mongodb $unwind 聚合管道
- 下一篇: 软测第二周作业WordCount