牛客练习赛13 F-皇后

链接:https://www.nowcoder.com/acm/contest/70/F
来源:牛客网

在一个n*n的国际象棋棋盘上有m个皇后。
一个皇后可以攻击其他八个方向的皇后(上、下、左、右、左上、右上、左下、右下)。
对于某个皇后,如果某一个方向上有其他皇后,那么这个方向对她就是不安全的。
对于每个皇后,我们都能知道她在几个方向上是不安全的。

现在我们想要求出t0,t1,...,t8,其中ti表示恰有i个方向是"不安全的"的皇后有多少个。

输入描述:

第一行两个整数n,m表示棋盘大小和皇后数量。
接下来m行每行两个整数ri,ci表示皇后坐标。
1 <= n, m <= 100,000
1 <= r

i

, c

i

<= n
数据保证没有皇后在同一个位置上。

输出描述:

一行九个整数表示答案。
空格隔开,结尾无空格
示例1

输入

8 4
4 3
4 8
6 5
1 6

输出

0 3 0 1 0 0 0 0 0
示例2

输入

10 3
1 1
1 2
1 3

输出

0 2 1 0 0 0 0 0 0

分析:这个题有点技巧,八个方向想象成四条直线,每条直线排序,一共四次排序,
每次排序后统计一遍就好了。
这题比赛的时候没做出来啊QAQ

#include<cstdio>
#include<algorithm>
using namespace std;
struct Node{
    int x,y,num;
}a[100100];
int sum[100100];
int t[10];
int cmp1(Node A,Node B)
{if(A.x==B.x) return A.y<B.y;return A.x<B.x;}
int cmp2(Node A,Node B)
{if(A.y==B.y) return A.x<B.x;return A.y<B.y;}
int cmp3(Node A,Node B)
{if(A.x+A.y==B.x+B.y) return A.x<B.x;return A.x+A.y<B.x+B.y;}
int cmp4(Node A,Node B)
{if(A.x-A.y==B.x-B.y) return A.x<B.x;return A.x-A.y<B.x-B.y;}
int main()
{
    int m;
    scanf("%d%d",&m,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].num=i;
    }
    
    sort(a,a+m,cmp1);
    for(int i=1;i<m;i++) 
        if(a[i-1].x==a[i].x) 
            {sum[a[i-1].num]++;sum[a[i].num]++;}
    sort(a,a+m,cmp2);
    for(int i=1;i<m;i++) 
        if(a[i-1].y==a[i].y) 
            {sum[a[i-1].num]++;sum[a[i].num]++;}
    sort(a,a+m,cmp3);
    for(int i=1;i<m;i++) 
        if(a[i-1].x+a[i-1].y==a[i].x+a[i].y) 
            {sum[a[i-1].num]++;sum[a[i].num]++;}
    sort(a,a+m,cmp4);
    for(int i=1;i<m;i++) 
        if(a[i-1].x-a[i-1].y==a[i].x-a[i].y) 
            {sum[a[i-1].num]++;sum[a[i].num]++;}
    
    for(int i=0;i<m;i++)
    t[sum[i]]++;
    for(int i=0;i<8;i++) printf("%d ",t[i]);
    printf("%d\n",t[8]);
    return 0;
}
View Code

 




posted @ 2018-03-16 22:47  ACRykl  阅读(184)  评论(0编辑  收藏  举报