POJ 2358|URAL 1034|Queens in Peaceful Positions

30 篇文章 0 订阅

原文地址:http://acm.timus.ru/problem.aspx?space=1&num=1034

题目

一个 N×N(N50) 的棋盘上有 N 个皇后。我们认为这个棋盘的皇后摆放方案是和平的仅当没有一个皇后与其他皇后在同一行、同一列、同一斜线上(因为可以互相攻击)。你需要找出一些方案使得对于一个和平的摆放,只改变其中三个皇后的位置,新的摆放仍然是和平的。

输入

输入第一行一个整数N
接下来 N 行每行2个整数xi,yi(1xi,yiN),表示第 i <script type="math/tex" id="MathJax-Element-211">i</script>个皇后的坐标。

输出

输出一行一个整数,表示有多少种改变皇后位置的方案满足条件(所有皇后是等价的,如果你只交换2个皇后,不算一种新方案)。

样例输入

4
2 1
1 3
3 4
4 2

样例输出

0

题解

考虑到每行每列都有一个皇后,改变3个皇后的位置的话,如果全改到一行里肯定是不合法的,因此我们只横向移动皇后(即改变y坐标,当然你只纵向移动也没问题,我们这里规定横向移动,这样竖向的移动其实是没有意义的,比如2行皇后调到4行,4行的皇后调到了2行【当然调到其他地方去就冲突不合法了】,相当于2行和4行的皇后横向调整)。然后因为N很小,所以我们枚举3个皇后,交换她们的横坐标(y坐标),这样横纵方向都是满足条件的,只要再判断斜方向是否冲突即可。

#include <cstdio>
#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值