@洛谷 P1562
题目描述
正如题目所说,这题是著名的N皇后问题。
输入格式
第一行有一个N。接下来有N行N列描述一个棋盘,“*” 表示可放 “.” 表示不可放。
输出格式
输出方案总数
输入输出样例
输入 #1
4
**.*
****
****
****
输出 #1
1
AC code:
import java.io.IOException;
import java.io.InputStream;
public class Main {
static int n, cnt, full, map[];
public static void main(String[] args) throws IOException {
InputReader in = new InputReader(System.in);
n = in.nextInt();
map = new int[n];
full = (1 << n) - 1;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) if (in.nextChar() == '.') map[i] += 1 << j;
dfs(0, 0, 0, 0);
System.out.print(cnt);
}
static void dfs(int row, int ld, int rd, int d) {
if (row == full) cnt++;
else {
int pos = full & ~(row | ld | rd | map[d]), p;
while (pos != 0) {
p = pos & -pos;
pos -= p;
dfs(row | p, (ld | p) << 1, (rd | p) >> 1, d + 1);
}
}
}
static class InputReader {
byte[] buff;
InputStream in;
int next, blen;
InputReader(InputStream in) { this(in, 1024); }
InputReader(InputStream in, int buffSize) {
this.in = in;
this.buff = new byte[buffSize];
}
int getByte() {
if (next >= blen)
try {
next = 0;
blen = in.read(buff);
if (blen == -1) return -1;
} catch (IOException e){ }
return buff[next++];
}
int nextInt() {
int n = 0, c = getByte();
while (c < '0' || c > '9') c = getByte();
while (c >='0' && c <='9') {
n = n * 10 + (c & 0xf);
c = getByte();
}
return n;
}
int nextChar() {
int c = getByte();
while (c <= 32 || c == 127) c = getByte();
return c;
}
}
}
没啥好讲的,位运算懂得都懂,但 pos & -pos 这就涉及到我知识盲区了,不知道为啥就是看不明白补码,只知道这种方式能取出二进制最高位