Very basic problem, but there are many kinds of search posture, feel used to get started is very good.
Test instructions: There is a 4*4 chess board, there are black and white lattice on the board, each time you can turn one of the lattice. If a lattice (x, y) is flipped, its adjacent front and back left and right four squares (if on the board) are also flipped. Now give you an initial checkerboard state, ask the minimum number of times to flip the board to full black or full white, and if it can't reach full black or all white, output impossible.
Only the 4*4 board, while the lattice only two sides of black and white. For the same lattice, turn two times and do not turn out no difference. A very small amount of data is to guide the human pressure to do after the violence. But you can enumerate all 65536 states to update the answer, or you can change from 0 grid-1 lattice-...-turn over 16 squares to increase the enumeration of the answer, meet the criteria to jump, or you can use BFS to search, you can also use DFS to constantly update the answer.
Here, pick the first and last one.
The first kind of fool algorithm, the code is very short, run up very long. All the possible upside-down states (1<<16 species) are all over once and loose can be done within the time limit. Pro-Test 204MS.
1#include <iostream>2 using namespacestd;3 Const intINF =0x7fffffff;4 Chars[4][4];5 intcs[ -] = {0x13,0x27, +, $,305,626,1252,2248,4880,8992,20032,35968,12544,29184,58368,51200};//Save the change value of the double I lattice6 intpo[ -] = {1,2,4,8, -, +, -, -, the, +,1024x768,2048,4096,8192,16384,32768};//Save 2^i7 intMain ()8 {9 intValue =0;Ten intCmin =inf; One CharC; A for(intI=0; i< -; i++) { -CIN >>C; - if(c = ='b') theValue + = (int) po[i]; - Else - Continue; - } + for(intI=0; i<65536; i++) {//Enumerate all States - intCou =0; + intCvalue =value; A for(intj=0;j< -; J + +) at if(I & (int) {Po[j]) { -cou++; -Cvalue ^=Cs[j]; - } - if(Cvalue = =0|| Cvalue = =65535)//All Black or all white - if(Cou <cmin) inCmin =cou; - } to if(Cmin = = inf) cout <<"Impossible"; + Elsecout << cmin <<Endl; - return 0; the}
View Code
Then the fourth kind. We can find that in fact only the first line is enumerated how to flip and expect to reach the black/white state, after each line in order to remain full black or full white, only the only flip possible. This will cut off a lot of unnecessary search volume.
1#include <iostream>2#include <cstdio>3#include <cstring>4#include <queue>5 using namespacestd;6 intDx[] = {0,0,0,1, -1};7 intDy[] = {0,1, -1,0,0};8 intAns =0x3f3f3f3f;9 intFlipintXxintYyinttmp//Flip Five squares in turnTen { One for(intI=0; i<5; i++) { A intx = xx + dx[i], y = yy +Dy[i]; - if(x >=0&& x <4&& y>=0&& y <4) -TMP ^=1<< (x *4+y); the } - returntmp; - } - //cur current line, num current number of steps, state current checkerboard status, flag indicates expected black or white + voidDfsintCurintNumintStateintflag) - { + if(cur = =4&& (state = =0xFFFF|| state = =0)) {//Update Answer AAns =min (ans, num); at } - if(cur = =4)return;//return Condition - inti = cur-1; - for(intj=0; j<4; J + +) {//make the previous line All Black/white - if((State & (1<< (i *4+ j)) >> (i *4+ j)) ^flag) { -State =Flip (cur, j, state); innum++; - Continue; to } + } -DFS (cur +1, NUM, state, flag); the } * voidSolveintSt) $ {Panax Notoginseng for(intI=0; i< -; i++) {//enumerate the first row - intnum =0, state =St; the for(intj=0; j<4; J + +) { + if(I & (1<<j)) { Astate = Flip (0, J, state); thenum++; + } - } $Dfs1, NUM, state,0); $Dfs1, NUM, state,1); - } - if(ans = =0x3f3f3f3f) thePuts"Impossible"); - Elseprintf"%d\n", ans);Wuyi } the intMain () - { Wu Chars[8]; - intSt =0; About for(intI=0; i<4; i++) { $scanf"%s", s); - for(intj=0; j<4; J + +) { -St <<=1; -St + = (s[j] = ='b') ?1:0; A } + } the Solve (ST); - return 0; $}
View Code
The BFs method is similar to DFS and is not mentioned. For a similar problem, the pressure + search is sufficient to solve most of the problems.
POJ 1753 enumeration + Mob Search