Queen K Question
Fzu game remains a question of the search problem K Queen did not do, the main idea is to decorate K queen on the chessboard of M*n, make the K queen not attack each other (here the meaning of the attack with "eight queens Problem", namely two queens can not be on the same line, the same column and the same slash). Which 1≤m*n≤150,1≤k≤50, time limit 10s
In fact, from the topic we can launch a very simple but very important conclusion, that is, Min (m, n) < 13, meaning that the shorter side of the board is not more than 12, so that the number of 150 will not be afraid of. Again, we can assert K <= min (m, N). Another simple conclusion is that
F[M][N][K] = F[n][m][k] (F[m][n][k] represents the m*n of the chessboard to place K-no-attack queen species number)
Second, we may think of a direct retrospective to the hard search, which unfortunately this is not feasible. Why not, many similar states repeat the search, we need to remove those similar states, that is, to add a strong pruning. It is not difficult to find that we are dealing with a chessboard, and the chessboard has some symmetrical properties. By using these properties we can effectively reduce the search space, so that the efficiency is greatly improved. (theoretically should be able to reduce the 1/4, I in the use process for convenience, reduced by 1/2)
Can it be faster. Remember before in the group to hear the discussion said N Queen has a super fast bit OP version, the Internet search search, found indeed very tough, if combined with the upper calculation and symmetry, it is quite perfect. (about n Queen bit version of the introduction can participate in the MATRIX67 blog of this article)
below is the AC code, 6.2S
Farmer Tri-Fist @seu #include <stdio.h> #include <string.h> typedef long Long i64;
I64 s[151][151][51];
int m, n, x, y;
int MASK;
I64 ans;
void Dfs (int m, int n, int row, int ld, INT rd, int num, int p, int index) {if (num = p) ans++; else if (Index < m) {if (num + m-index > P) DFS (m, N, Row, LD << 1, RD >> 1, nu
M, p, index + 1);
int pos = MASK & ~ (Row | rd | ld);
while (POS!= 0) {int pp = pos &-pos;
pos = pos-pp;
DFS (M, n, Row + PP, (ld + PP) << 1, (rd + pp) >> 1, num + 1, p, index + 1);
}} i64 solve (int m, int n, int p) {if (S[m][n][p]!=-1) return s[m][n][p];
if (p > N) return 0;
I64 ret = 0;
int I, J;
for (j = 0; J < N; j +) {int pos = 1 << (n-1-J);
Ans = 0;
DFS (M, N, POS, pos << 1, POS >> 1, 1, p, 1);
ret + ans;} S[m][n][p] = ret;
return ret;
int main () {int i, J;
Memset (S,-1, sizeof (s));
while (scanf ("%d%d%d%d", &m, &n, &x, &y) = = 4) {if (M < n && n > 31) {
int t = m;
m = n;
n = t;
} if (y > N) y = n;
MASK = (1 << N)-1;
i64 res = 0;
if (x = = 0) res++, x = 1;
for (i = x; i <= y; i++) {for (j = i; J <= m; j) res = Solve (j, N, i);
printf ("%lld\n", res);
return 0; }
Postscript:
1. Through the experiment, when given M*n (n > M) chessboard, in the N < 31 of the scope to make n larger, conversely will be m,n exchange processing, so that can fully use the scope of the int range of the effect of the bitwise operation. In fact, when the 64-bit bit operation, the speed is reduced.
2. If you use a line of symmetry, we just enumerate the first queen in a row of half of the column can be transferred from: http://www.cnblogs.com/drizzlecrj/archive/2007/10/04/913703.html