The “eight queens puzzle” is the problem of placing eight chess queens on an 8×8 chessboard so that no two queens threaten each other. Thus, a solution requires that no two queens share the same row, column, or diagonal. The eight queens puzzle is an example of the more general N queens problem of placing N non-attacking queens on an N×N chessboard. (From Wikipedia - “Eight queens puzzle”.)
Here you are NOT asked to solve the puzzles. Instead, you are supposed to judge whether or not a given configuration of the chessboard is a solution. To simplify the representation of a chessboard, let us assume that no two queens will be placed in the same column. Then a configuration can be represented by a simple integer sequence (Q1 ,Q2 ,⋯,QN ), where Qi
is the row number of the queen in the i-th column. For example, Figure 1 can be represented by (4, 6, 8, 2, 7, 1, 3, 5) and it is indeed a solution to the 8 queens puzzle; while Figure 2 can be represented by (4, 6, 7, 2, 8, 1, 9, 5, 3) and is NOT a 9 queens’ solution.
8q.jpg 9q.jpg
Figure 1 Figure 2
Input Specification:
Each input file contains several test cases. The first line gives an integer K (1<K≤200). Then K lines follow, each gives a configuration in the format "N Q1 Q2 … QN ", where 4≤N≤1000 and it is guaranteed that 1≤Qi ≤N for all i=1,⋯,N. The numbers are separated by spaces.
Output Specification:
For each configuration, if it is a solution to the N queens problem, print YES in a line; or NO if not.
Sample Input:
4
8 4 6 8 2 7 1 3 5
9 4 6 7 2 8 1 9 5 3
6 1 5 2 6 4 3
5 1 3 5 2 4
Sample Output:
YES
NO
NO
YES
题意
有K组数据。
每组数据给出棋盘尺寸N x N,以及一个长度为N的序列,第i个元素代表列数为i的皇后的行数。
求每组数据中是否是合法的摆放。
思路
合法的拜访是任意两个皇后不在同一横轴、纵轴和对角线上,所以我们使用X[]、Y[]、cnt1[]、cnt2[]分别存储与横轴垂直的直线族、与纵轴垂直的直线族、正反对角线直线族上的皇后个数。
对于X[],Y[]非常简单,对于尺寸为N的棋盘,有N条与横轴垂直和N条与纵轴垂直的直线,反对角线也就是解析式为y = x + b的直线有2 * N - 1条(b = - N + 1, - N + 2,…,0, 1, 2, …, N - 1),我们加一个偏移值N,将b映射到1到2N-1上,也就是对于一个直线y = x + b0,直线上的皇后数存放在cnt1[b0 + N]中。同理,正对角线y = -x + b族存放在cnt2中。
读入输入的时候统计各族直线上的皇后数,然后判断是否有一条直线上的皇后数大于1,有则不合法,否则合法。
代码
#include <cstdio>
#include <algorithm>
#define MAX_N 1005
using namespace std;
int cnt1[MAX_N * 2], cnt2[MAX_N * 2], X[MAX_N], Y[MAX_N];
int check(int N){
for(int i = 1; i <= N; i++){
if(X[i] > 1 || Y[i] > 1) return false;
}
for(int i = 0, l = 2 * N; i < l; i++){
if(cnt1[i] > 1) return false;
if(cnt2[i] > 1) return false;
}
return true;
}
int main() {
int K;
scanf("%d", &K);
while (K-- > 0) {
int N;
scanf("%d", &N);
fill(cnt1, cnt1 + N + N, 0);
fill(cnt2, cnt2 + N + N, 0);
fill(X, X + N + 1, 0);
fill(Y, Y + N + 1, 0);
for(int x = 1, y; x <= N; x++){
scanf("%d", &y);
X[x]++;
Y[y]++;
cnt1[y - x + N]++;
cnt2[x - y + N]++;
}
printf(check(N) ? "YES\n" : "NO\n");
}
return 0;
}