题目描述
一个城市遭到了 MM 次轰炸,每次都炸了一个每条边都与边界平行的矩形。
在轰炸后,有 NN 个关键点,指挥官想知道,它们有没有受到过轰炸,如果有,被炸了几次,最后一次是第几轮。
输入格式
第一行,两个整数:M,NM,N。
以下 MM 行,每行四个整数:x_1x1、y_1y1、x_2x2、y_2y2,表示被轰炸的矩形的左上角坐标和右下角坐标(比如1 3 7 10
就表示被轰炸的地方是从(1,3)(1,3)到(7,10)(7,10) 的矩形)。
再以下 NN 行,每行两个整数,表示这个关键点的坐标。
输出格式
共 NN 行,
每行第一个字符为 YES
或 NO
,表示是否被轰炸,若为 YES
,在一个空格后为两个整数,表示被炸了几次和最后一次是第几轮。
标签:模拟
难度:普及-
题目传送门:轰炸II - 洛谷
题析
好惨一城逝(是你吗吴克蓝?)
这题就是一个非常典型的二维前缀和题
所谓二维前缀和,就是把一维的转换到二维(废话)
怎么实现呢?
一维前缀和怎么做?
当前加c,结束位置下一位减c
二维原理是相同的
起始点加c不变
列的终止怎么办?就是在坐标为结束点的x+1,开始点的y减1的点就行了
行的终止同理,在坐标为结束点的y+1,开始点的x的点减1
也就是矩形右上点再向右一个点和坐下点再向下一个点减1
这个时候坐标为结束点x+1,y+1的坐标点被减了两遍,再加上1
这就是逻辑了
AC代码
#include<bits/stdc++.h>
using namespace std;
int s[2010][2010];
int a[2010][2010];
void add(int x1,int y1,int x2,int y2)
{
s[x1][y1]+=1;
s[x1][y2+1]-=1;
s[x2+1][y1]-=1;
s[x2+1][y2+1]+=1;
}
void add2(int x1,int y1,int x2,int y2,int q)
{
a[x1][y1]=q;
a[x1][y2+1]=-q;
a[x2+1][y1]=-q;
a[x2+1][y2+1]=q;
}
int main(){
int q,n;
cin>>q>>n;
for(int i=1;i<=q;i++)
{
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
add(x1,y1,x2,y2);
add2(x1,y1,x2,y2,i);
}
while(n--)
{
int x,y;
cin>>x>>y;
if(s[x][y]!=0)
cout<<"YES"<<' '<<s[x][y]<<' '<<a[x][y]<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
完awa