Test instructions
given 4*4 's chessboard, each position is "B","W" or " ", indicating black, white, or space. The target game is defined as four children with one row, one column, or the same color on a diagonal line. The black and white alternating, the beginning of either party first, the minimum number of steps to achieve the target chess.
Analysis
Define the variables first:
Basic Q(1)wt[2][2] record space position
(2)int p[4][4] record value, Black to save 1, White to save 2, space to save 0
Hash table Hash(1)Long Long data, the value of the game, is converted to the ten -binary storage
(2)next, the adjacent table is stored in bits
(3)has, the number of this position
lmt=100000009;
HD[LMT] memory Hash table header
The subject requires the minimum number of steps to achieve the goal of the game, you can use the wide search, but the wide search easy to explode space, and not very good to write, then use the iterative deepening search.
Implementation of iterative deepening search
Int check (void) {horizontal judgment; top left-right bottom diagonal judgment;//diagonal (I,J) satisfies i=j upper right-left lower diagonal;//diagonal (I,J) satisfies i+j=4+1=5} void Swap (&i , &j) {i^=j^=i^=j;//How do you write all the same?} int update (int u,int tag)//INSERT, find, Delete to a procedure, because many parts are the same {Int key=u%lm; Gets the collection for (Intk=hd[key];k;k=hash[k].next)//Enumeration data if (HASH[K].DATA==U)//if equal to if (typ==2) return hash[k].has;//If the lookup process returns has else {hash[k].has^=1; The state of has changed return1; Direct Exit} if (TYP^2)//If it is not a lookup process, it is the insertion process, because the removal process must be completed on the {hash[++tot].data=u; Hash[tot].has=1; Hash[tot].next=hd[key]; Hd[key]=tot; Insert} return 0; Returns 0, satisfies lookup cannot find} int can (int x,int y)//judgment coordinate is not satisfied {Return x+1&&x<4&&y+1&&y<4;//0<=x,y& lt;=3} int DFS (int dep,int lmt,int turn)//DEP The current step, lmt depth, turn which party {if (DEP==LMT) return check ();//If the target depth is reached, the row will not be judged. Long Longgt=get (); Update (gt,0); The hash table is inserted into the current state int d=0; StandardNote for (inti=0;! d&&i<2;i++)//enumerate which spaces move for (intj=0;! d&&j<4;j++)//enumerate where to go if (Can (P.wt[i][0]+dx[j],p.wt[i][1]+dy[j],turn))//If you can move { INTX=P.WT[I][0]+DX[J],Y=P.WT[I][1]+DY[J]; X, y record the shifted bit swap (p.p[p.wt[i][0]][p.wt[i][1]],p.p[x][y]); P.WT[I][0]+=DX[J]; P.WT[I][1]+=DY[J]; Swap if (!update (Get (), 2)) D|=dfs (DEP+1,LMT, (turn-1^1) +1); If you do not have this status, continue to DFS p.wt[i][0]-=dx[j]; P.WT[I][1]-=DY[J]; Swap (p.p[p.wt[i][0]][p.wt[i][1]],p.p[x][y]);//restore} update (gt,0); Remove the current state from the hash table return D; Return tag} Int main (void) {... for (cnt=0;! DFS (0,cnt,0) &&! DFS (0,cnt,1); cnt++); Printf ("%d\n", CNT); Return 0;}
The code is long, so the problem is God-like water problem is almost ...
Code
#include <cstdio> #include <cstring> #include <cstdlib> using namespace std; const int LM=10000009;CONST int dx[4]={0,0,-1,1};const int dy[4]={-1,1,0,0}; struct a{int p[4][6]; int wt[2][2];} P;struct h{long Longdata; int Next,has;} Hash[3000000];int Hd[lm],tot;int CNT; int check (void) {int D; for (inti=0;i<4;i++) {d=1; for (intj=1;j<4;j++) if (P.p[i][j]^p.p[i][0]) {d=0;break;} if (d) return 1; } for (inti=0;i<4;i++) {d=1; for (intj=1;j<4;j++) if (P.p[j][i]^p.p[0][i]) {d=0;break;} if (d) return 1; } d=1; for (inti=1;i<4;i++) if (P.p[0][0]^p.p[i][i]) {d=0;break;} if (d) return1; B=w; for (inti=1;i<4;i++) if (P.p[0][4]^p.p[i][4-i]) {d=0;break;} return D;} A long long get (void) {long longsum=0,mtp=1; for (inti=3;i+1;i--) for (intj=3;j+1;j--) sum+=mtp*p.p[i][j],mtp*=10; return sum;} int update (Long long U,intTyp) {intkey= (int) (U%LM); for (Intk=hd[key];k;k=hash[k].next) if (hash[k].data==u) if (typ==2) if (Hash[k].has) return 1; Else else {hash[k].has^=1; RETURN1; } if (typ^2) {hash[++tot].data=u; Hash[tot].has=1; Hash[tot].next=hd[key]; Hd[key]=tot; } return 0;} int can (int x,int y,int turn) {Returnx+1&&x<4&&y+1&&y<4&&p.p[x][y]==turn;} void swap (int &i,int &j) {i^=j^=i^=j;} int DFS (int dep,int lmt,int turn) {if (DEP==LMT) return check (); Long Longgt=get (); Update (gt,1); int d=0; for (inti=0;! d&&i<2;i++) for (intj=0;! d&&j<4;j++) if (Can (P.wt[i][0]+dx[j],p.wt[i][1]+dy[j],turn)) {Intx=p.wt[i] [0]+dx[j],y=p.wt[i][1]+dy[j]; Swap (p.p[p.wt[i][0]][p.wt[i][1]],p.p[x][y]); P.WT[I][0]+=DX[J]; P.WT[I][1]+=DY[J]; if (!update (Get (), 2)) D|=dfs (DEP+1,LMT, (turn-1^1) +1); P.WT[I][0]-=DX[J]; P.WT[I][1]-=DY[J]; Swap (p.p[p.wt[i][0]][p.wt[i][1]],p.p[x][y]); } update (gt,0); return D;} int main (void) {int c=0; chars; for (inti=0;i<4;i++) {for (intj=0;j<4;j++) {scanf ("%c", &s); p.p[i][j]= (s== ' B '? 2:s== ' W '? 1:0); } scanf ("\ n"); } for (inti=0;i<4;i++) for (intj=0;j<4;j++) if (!p.p[i][j]) p.wt[c][0]=i,p.wt[c++][1]=j; for (cnt=0;! DFS (0,cnt,1) &&! DFS (0,cnt,2); cnt++); printf ("%d\n", CNT); return 0;}
Summary
(1) When the wrong question or method is found to be wrong, we should learn to adjust the program, and should not be wasted, completely negative.
(2) The common idea of the program, several similar processes put into a process to complete, to achieve the effect of simplification
(3) when using wide search to find space is very large or unable to estimate space, you can consider iterative deepening search.
Code[vs] 10,044 zi Lian Chess