题目描述
输入输出格式
输入格式:
第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。
输出格式:
对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。
输入输出样例
说明
很显然,我们搜索时应注意搜索空格,而不是马……
显然,如果读入map[i][j]!=所需要的,显然ans++,所以我们可以求出ans的下界,即mnnd(min_need)。
注意有些优化在里面,看代码就知道了。
AC代码如下:
#include<cstdio> #include<algorithm> #include<iostream> using namespace std; const int check[6][6]={{},{0,1,1,1,1,1},{0,0,1,1,1,1},{0,0,0,-1,1,1},{0,0,0,0,0,1},{0,0,0,0,0,0}}; const int dx[]={-2,-2,-1,1,-1,1,2,2}; const int dy[]={-1,1,2,2,-2,-2,-1,1}; int mxnd,mnnd,a[1<<3][1<<3],x,y,t; char b; bool dfs(int step,int x,int y,int nd,int last) { if(step+nd>mxnd) return 0; if(nd==0) return 1; int xx,yy,now; for(int i=0;i<=7;i++) if(i!=7-last) { xx=x+dx[i];yy=y+dy[i]; now=nd; if(xx<=5&&xx>=1&&yy<=5&&yy>=1) { if(a[xx][yy]==check[xx][yy]&&a[xx][yy]!=check[x][y]) now++; if(a[xx][yy]!=check[xx][yy]&&a[xx][yy]==check[x][y]) now--; if(check[xx][yy]==-1) now--; if(check[x][y]==-1) now++; a[xx][yy]^=a[x][y];a[x][y]^=a[xx][yy];a[xx][yy]^=a[x][y]; if(dfs(step+1,xx,yy,now,i)) return 1; a[xx][yy]^=a[x][y];a[x][y]^=a[xx][yy];a[xx][yy]^=a[x][y]; } } return 0; } int main() { scanf("%d",&t); while(t--) { mnnd=0; for(int i=1;i<=5;i++) for(int j=1;j<=5;j++) { cin>>b; a[i][j]=b-‘0‘; if(b==‘*‘) x=i,y=j,a[i][j]=-1; if(a[i][j]!=check[i][j]) mnnd++; } bool flag=0; for(int i=mnnd;i<=16;i++) { mxnd=i; if(dfs(0,x,y,mnnd,-1)) { printf("%d\n",i-1); flag=1; break; } } if(!flag) printf("-1\n"); } return 0; }