P3913 车的攻击

题目描述

N \times NN×N 的国际象棋棋盘上有KK 个车,第ii个车位于第R_iRi行,第C_iCi 列。求至少被一个车攻击的格子数量。

车可以攻击所有同一行或者同一列的地方。

输入格式

第1 行,2 个整数N,KN,K。

接下来K 行,每行2 个整数R_i,C_iRi,Ci

输出格式

1 个整数,表示被攻击的格子数量。

输入输出样例

输入 #1
3 2
1 2
2 2
输出 #1
7

说明/提示

• 对于30% 的数据,1 \le N \le 10^3; 1 \le K \le 10^31N103;1K103;

• 对于60% 的数据,1 \le N \le 10^6; 1 \le K \le 10^61N106;1K106;

• 对于100% 的数据,1 \le N \le 10^9; 1 \le K \le 10^6; 1 \le R_i , C_i \le N1N109;1K106;1Ri,CiN。

题目大意:

求出被车攻击到的格子数量。

 

思路分析:

 

 

黄色的是攻击到的区域,白色的是攻击不到的区域。

剩下的面积=3*3-(3-1)*(3-2)

由此可以得到公式:n*n-(n-不一样的行)*(n-不一样的列)=被攻击到的格子数量

我们先排序,在求出不一样的行和不一样的列,再计算被攻击到的格子数量

 

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
long long r[1001000],c[1001000];
long long n,k;
long long ans,h,l;
int px(long long a,long long b){
    return a<b;
}
int main(){
    scanf("%lld%lld",&n,&k);
    for(int i=1;i<=k;i++){
        scanf("%lld%lld",&r[i],&c[i]);
    } 
    sort(r+1,r+1+k,px);//排序
    sort(c+1,c+1+k,px);
    for(int i=1;i<=k;i++){
        if(r[i]!=r[i+1]){
            h++;
        }
        if(c[i]!=c[i+1]){
            l++; 
        } 
    }
    printf("%lld\n",n*n-(n-h)*(n-l));//公式
    return 0;
}

 

posted @ 2020-05-08 12:24  shanxx  阅读(179)  评论(0编辑  收藏  举报