题目描述
输入输出格式
输入格式:第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。
对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。
输入输出样例
Solution:
又是变量名打错,调了有一会儿~滑稽~!
本题直接切入点是步数不超过$15$,很自然想到迭代加深搜索。
那么直接限制深度搜,一个可行性剪枝就是统计一下当前没有被还原的棋子个数,若大于步数则直接剪掉。
(瞎几把乱搞一通就好了,关键注意判重,不能回到上一个点,否则卡死循环。)
代码:
1 #include<bits/stdc++.h> 2 #define il inline 3 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) 4 using namespace std; 5 int T,ans,stx,sty,w[6][6],ed[6][6]={ 6 0,0,0,0,0,0, 7 0,1,1,1,1,1, 8 0,0,1,1,1,1, 9 0,0,0,-1,1,1, 10 0,0,0,0,0,1, 11 0,0,0,0,0,0 12 }; 13 char s; 14 int dx[8]={1,1,-1,-1,2,2,-2,-2},dy[8]={2,-2,2,-2,1,-1,1,-1}; 15 bool f; 16 il void dfs(int x,int y,int t,int lstx,int lsty){ 17 if(!t)return; 18 int tot=0; 19 For(i,1,5) For(j,1,5) 20 if(w[i][j]!=ed[i][j])tot++; 21 if(!tot){f=1;return;} 22 if((tot>>1)>t)return; 23 For(i,0,7){ 24 int xx=dx[i]+x,yy=dy[i]+y; 25 if(xx>0&&xx<6&&yy>0&&yy<6&&(xx!=lstx|yy!=lsty)){ 26 swap(w[xx][yy],w[x][y]),dfs(xx,yy,t-1,x,y),swap(w[xx][yy],w[x][y]); 27 } 28 } 29 } 30 il bool solve(){ 31 f=0; 32 For(t,1,16){ 33 dfs(stx,sty,t,0,0); 34 if(f){ans=t;return 1;} 35 } 36 return 0; 37 } 38 int main(){ 39 ios::sync_with_stdio(0); 40 cin>>T; 41 while(T--){ 42 For(i,1,5) For(j,1,5){ 43 cin>>s; 44 if(s=='1')w[i][j]=1; 45 if(s=='*')w[i][j]=-1,stx=i,sty=j; 46 if(s=='0')w[i][j]=0; 47 } 48 if(solve())cout<<ans-1<<'\n'; 49 else cout<<-1<<'\n'; 50 } 51 return 0; 52 }