【PAT】A1128 N Queens Puzzle【八皇后问题】

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 (Q​1​​ ,Q​2​​ ,⋯,Q​N​​ ), where Q​i
​​ 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 Q​1​​ Q​2​​ … Q​N​​ ", where 4≤N≤1000 and it is guaranteed that 1≤Q​i​​ ≤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;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值