题解 P3913 【车的攻击】
本题数据已增强,但是做法不变,仅将读入和输出换成stdio的即可
题解好少啊,赶紧水一波。
题目要咱求能被攻击到的格子,但是如果硬处理的话超时是妥妥的,所以咱得想个数学办法,不能只靠模拟来打暴力。
首先考虑能不能直接将x轴与y轴有车的点先全部记录下来,然后将有车的行的数量和有车的列的数量记录下来,然后*n再相加,但是这样显然不可行,因为这样会导致在行列交汇处的点呗重新算2次。
既然被重新计算了,那我们把他们都删掉不就可以了吗?
不难看出,交叉点的个数就是有车的行数*有车的列数,那么就不难导出公式:
然后就是统计一共有几行几列有车了,这里就要用到我大stl中的一员大将:unique,也就是去重,通俗来讲,这个玩应的用法一般是
unique(数组名,数组名+大小)
(没错和sort几乎一模一样)
然后值得注意的有两点:
第一点:在
第二点:
利用c++可以指针相加减的特点,我们可以通过 unique-数组指针 来知道去重之后数组的“大小”(这里听不懂没关系,往下看代码,背住用法就好)
下面放ac代码
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
#define ll long long
const int maxn=1e6+5;
using namespace std;
ll n,k;
ll x[maxn],y[maxn];
int main(){
// freopen("test.in","r",stdin);
//cin>>n>>k;
scanf("%lld%lld",&n,&k);
for(ll i=0;i<k;i++){
//cin>>x[i]>>y[i];
scanf("%lld%lld",&x[i],&y[i]);
}
sort(x,x+k);
sort(y,y+k);
ll sizex=unique(x,x+k)-x;
ll sizey=unique(y,y+k)-y;
//cout<<n*n-(n-sizex)*(n-sizey);
printf("%lld",n*n-(n-sizex)*(n-sizey));
return 0;
}
很简短对不对,嘻嘻。