1 条题解

  • 0

    题意分析

    给定一个 N×NN \times N 的棋盘,初始摆放 NN 个皇后且互不攻击(和平位置)。要求通过恰好交换3个皇后的位置,计算能生成的新和平位置的数量(重复不计)。

    解题思路

    1. 组合选择:从 NN 个皇后中选3个,共 C(N,3)C(N,3) 种组合。
    2. 排列交换:对选中的3个皇后进行全排列(3!=63! = 6 种方式),生成新布局。
    3. 合法性检查:确保新布局无同行、同列或同对角线的皇后。
    4. 去重:通过坐标哈希或排序避免重复计数。

    实现步骤

    1. 输入处理:读取初始皇后位置,存储为集合或列表。
    2. 三重循环枚举:遍历所有 C(N,3)C(N,3) 个皇后三元组。
    3. 排列生成:对每个三元组生成6种排列,构造新棋盘。
    4. 冲突检测:检查新棋盘是否满足N皇后规则。
    5. 结果统计:用哈希表或集合去重,统计合法新解的数量。

    代码实现

    #include <cstring>
    #define FOR(i,j,k) for(i=j;i<=k;++i)
    #define rep(i,j,k) for(i=j;i<k;++i)
    
    int col[64], rb[256], rt[256];
    int n;
    
    inline void roll(int i, int j, int k) {
        int a = col[i], b = col[j], c = col[k];
        col[i] = b; col[j] = c; col[k] = a;
    }
    
    inline bool judge() {
        int i;
        memset(rb, 0, sizeof rb);
        memset(rt, 0, sizeof rt);
        FOR(i,1,n) {
            if (rb[i + col[i] + 128]) return false;
            if (rt[i - col[i] + 128]) return false;
            rb[i + col[i] + 128] = true;
            rt[i - col[i] + 128] = true;
        }
        return true;
    }
    
    int main() {
        int x, y, i, j, k, s = 0;
        scanf("%d", &n);
        FOR(i,1,n) scanf("%d%d", &x, &y), col[x] = y;
    
        FOR(i,1,n) rep(j,1,i) rep(k,1,j) {
            roll(i, j, k);
            if (judge()) ++s;
            roll(i, j, k);
            if (judge()) ++s;
            roll(i, j, k);
        }
        printf("%d\n", s);
        return 0;
    }
    
    • 1

    信息

    ID
    1359
    时间
    1000ms
    内存
    256MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者