given the target point on the M*n board, the minimum number of Queens can be used to guard all target points.
like the eight Queens procedure, the 2-D array marks rows, columns, main diagonals, and diagonal lines.
There is an acceleration of the technique, after the test found that the 10*10 board all Guards need at least 5, so the upper limit is 5, when maxd equals 5 o'clock direct output, do not search.
#include <cstdio> #include <cstring>using namespace std;const int maxn=11;int N,m,t,maxd;bool G[MAXN][MAXN] , Vis[4][maxn*2];bool Guard () {for (Int. i=0;i<n;i++) for (int j=0;j<m;j++) if (G[i][j]&&!vis[0] [I]&&!VIS[1][J]&&!VIS[2][I+J]&&!VIS[3][I-J+MAXN]) return false; return true;} BOOL Dfs (int i,int j,int d) {if (D==maxd) {if (Guard ()) return true; return false; } while (I<n) {while (j<m) {bool Tmp1=vis[0][i],tmp2=vis[1][j],tmp3=vis[2][i+j],tmp4=vis[3][i-j+m AXN]; Vis[0][i]=vis[1][j]=vis[2][i+j]=vis[3][i-j+maxn]=true; if (Dfs (i,j+1,d+1)) return true; Vis[0][i]=tmp1,vis[1][j]=tmp2,vis[2][i+j]=tmp3,vis[3][i-j+maxn]=tmp4; ++j; } j%=m,++i; } return false;} int main () {while (scanf ("%d", &n), N) {scanf ("%d", &m); memset (G,0,sizeof (g)); for (int i=0;i<n;i++) {getchar (); for (intj=0;j<m;j++) if (getchar () = = ' X ') g[i][j]=true; } for (Maxd=0;maxd<5;++maxd) {memset (vis,0,sizeof (VIS)); if (Dfs (0,0,0)) break; } printf ("Case%d:%d\n", ++t,maxd); } return 0;}
Uva11214-guarding the Chessboard