洛谷 P2324 [SCOI2005]騎士精神 解題報告
阿新 • • 發佈:2018-08-02
else if urn swa swap 報告 while 就是 include har
P2324 [SCOI2005]騎士精神
題目描述
輸入輸出格式
輸入格式:
第一行有一個正整數T(T<=10),表示一共有N組數據。接下來有T個5×5的矩陣,0表示白色騎士,1表示黑色騎士,*表示空位。兩組數據之間沒有空行。
輸出格式:
對於每組數據都輸出一行。如果能在15步以內(包括15步)到達目標狀態,則輸出步數,否則輸出-1。
一看到15,莫名的想到叠代加深。
然後發現這個玩意12都跑不過去。想過估價函數,但感覺操作次數會很多就放棄了。
實際上這個題的重點就是估價函數
設估價函數為與目標狀態不同的點的個數+1(這個+1是為了最後一步空白的)
然後跑IDA* 就行了(事實是A*更快)
Code:
#include <cstdio> const int N=6; int t,sta[N][N],step,ex,ey,flag; int to[N][N]= { {0,0,0,0,0,0}, {0,1,1,1,1,1}, {0,-1,1,1,1,1}, {0,-1,-1,0,1,1}, {0,-1,-1,-1,-1,1}, {0,-1,-1,-1,-1,-1}, }; inline int estimate() { int res=0; for(int i=1;i<=5;i++) for(int j=1;j<=5;j++) if(to[i][j]!=sta[i][j]) res++; return res; } int dx[9]={0,-2,-1,1,2,2,1,-1,-2}; int dy[9]={0,1,2,2,1,-1,-2,-2,-1}; inline void Swap(int &x,int &y) { int tmp=x; x=y; y=tmp; } void dfs(int dep,int x,int y) { if(flag) return; if(estimate()+dep>step+1) return; if(step==dep){flag=1;return;} for(int i=1;!flag&&i<=8;i++) { int X=x+dx[i],Y=y+dy[i]; if(X>0&&Y>0&&X<=5&&Y<=5) { Swap(sta[x][y],sta[X][Y]); dfs(dep+1,X,Y); Swap(sta[x][y],sta[X][Y]); } } } void work() { flag=0; if(estimate()==0) {printf("0\n");return;} for(step=1;step<=15;step++) { dfs(0,ex,ey); if(flag) { printf("%d\n",step); return; } } printf("-1\n"); } int main() { scanf("%d",&t); while(t--) { for(int i=1;i<=5;i++) { scanf("\n"); for(int j=1;j<=5;j++) { char c; scanf("%c",&c); if(c==‘*‘) ex=i,ey=j,sta[i][j]=0; else if(c==‘1‘) sta[i][j]=1; else sta[i][j]=-1; } } work(); } return 0; }
2018.8.2
洛谷 P2324 [SCOI2005]騎士精神 解題報告