P2324 [SCOI2005]騎士精神
阿新 • • 發佈:2018-02-16
flag while span style dfs img tps 空格 -o
題目描述
輸入輸出格式
輸入格式:
第一行有一個正整數T(T<=10),表示一共有N組數據。接下來有T個5×5的矩陣,0表示白色騎士,1表示黑色騎士,*表示空位。兩組數據之間沒有空行。
輸出格式:
對於每組數據都輸出一行。如果能在15步以內(包括15步)到達目標狀態,則輸出步數,否則輸出-1。
輸入輸出樣例
輸入樣例#1: 復制2 10110 01*11 10111 01001 00000 01011 110*1 01110 01010 00100輸出樣例#1: 復制
7 -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; }
P2324 [SCOI2005]騎士精神