m皇后(牛客网)

题目链接: 点击打开链接

要求出t 0 ,t 1 ,...,t 8 ,其中t i 表示恰有i个方向是"不安全的"的皇后有多少个。

2018.3.31 更新:妈耶为啥我的博客没了,还要重新写一遍???WOC???不记得了啊。

看着代码我回忆回忆算法,应该是把一个方向的边界的两个算出来后比较中间的,一共算四个方向,斜率正负一和上下四个方向。


记得当时题目意思读错了写了个错代码在注释里,是算八个方向各有几个几个来着好像。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
#define INF 10000000000
typedef pair<int, int> P;
#define f first
#define s second
#define N 100001
const int mod = 10007;

P p[N];
int n, m, mx[N * 2], mn[N * 2], ans[N], cnt[9];

void solve1()
{
    memset(mx, 0, sizeof mx);
    memset(mn, 0x3f, sizeof mn);
    for(int i = 0; i < m; i++){
        mx[p[i].f] = max(mx[p[i].f], p[i].s);
        mn[p[i].f] = min(mn[p[i].f], p[i].s);
    }
    for(int i = 0; i < m; i++){
        if(p[i].s == mx[p[i].f] && p[i].s == mn[p[i].f]){
            continue;
        }else if(p[i].s == mx[p[i].f] || p[i].s == mn[p[i].f]){
            ans[i] += 1;
        }else{
            ans[i] += 2;
        }
    }
}

void solve2()
{
    memset(mx, 0, sizeof mx);
    memset(mn, 0x3f, sizeof mn);
    for(int i = 0; i < m; i++){
        mx[p[i].s] = max(mx[p[i].s], p[i].f);
        mn[p[i].s] = min(mn[p[i].s], p[i].f);
    }
    for(int i = 0; i < m; i++){
        if(p[i].f == mx[p[i].s] && p[i].f == mn[p[i].s]){
            continue;
        }else if(p[i].f == mx[p[i].s] || p[i].f == mn[p[i].s]){
            ans[i] += 1;
        }else{
            ans[i] += 2;
        }
    }
}

void solve3()
{
    int x;
    memset(mx, 0, sizeof mx);
    memset(mn, 0x3f, sizeof mn);
    for(int i = 0; i < m; i++){
        x = p[i].f - p[i].s + n;
        mx[x] = max(mx[x], p[i].s);
        mn[x] = min(mn[x], p[i].s);
    }
    for(int i = 0; i < m; i++){
        x = p[i].f - p[i].s + n;

        if(p[i].s == mx[x] && p[i].s == mn[x]){
            continue;
        }else if(p[i].s == mx[x] || p[i].s == mn[x]){
            ans[i] += 1;
        }else{
            ans[i] += 2;
        }
    }
}

void solve4()
{
    int y;
    memset(mx, 0, sizeof mx);
    memset(mn, 0x3f, sizeof mn);
    for(int i = 0; i < m; i++){
        y = p[i].f + p[i].s;
        mx[y] = max(mx[y], p[i].f);
        mn[y] = min(mn[y], p[i].f);
    }
    for(int i = 0; i < m; i++){
        y = p[i].f + p[i].s;

        if(p[i].f == mx[y] && p[i].f == mn[y]){
            continue;
        }else if(p[i].f == mx[y] || p[i].f == mn[y]){
            ans[i] += 1;
        }else{
            ans[i] += 2;
        }
    }
}

int main()
{
    scanf("%d%d", &n, &m);

    for(int i = 0; i < m; i++)
        scanf("%d%d", &p[i].f, &p[i].s);

    solve1();
    solve2();
    solve3();
    solve4();

    for(int i = 0; i < m; i++)
        cnt[ans[i]]++;

    for(int i = 0; i <= 8; i++)
        printf("%d%c", cnt[i], i == 8?'\n':' ');

    return 0;
}


/**
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
#define INF 100000000
typedef pair<int, int> P;
#define N 100001
const int mod = 10007;

int ans[9];
int heng[N], shu[N], zuo[N * 2], you[N * 2];
int n, m, x, y;
int cnt;

int main()
{
    scanf("%d%d", &n, &m);

    for(int i = 0; i < m; i++){
        scanf("%d%d", &x, &y);
        cnt = 0;

        heng[y]++;
        shu[x]++;
        zuo[x + y]++;
        you[y - x + n]++;
    }

    for(int i = 1; i <= n; i++){
        if(heng[i] > 1){
            ans[3] += heng[i] - 1;
            ans[4] += heng[i] - 1;
        }
        if(shu[i] > 1){
            ans[1] += shu[i] - 1;
            ans[2] += shu[i] - 1;
        }
    }

    for(int i = 0; i <= n * 2; i++){
        if(zuo[i] > 1){
            ans[5] += zuo[i] - 1;
            ans[7] += zuo[i] - 1;
        }
        if(you[i] > 1){
            ans[6] += you[i] - 1;
            ans[8] += you[i] - 1;
        }
    }

    for(int i = 1; i <= 8; i++)
        printf("%d%c", ans[i], i == 8?'\n':' ');

    return 0;
}
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值