【题意】:
这个题目的意思是:
有一个监视器管辖的范围用二维坐标的左下角和右上角来表示,然后有一个小偷在某个位置活动,请问能否把小偷给活动范围全部监视到。
【题解】:
1、二维差分数组维护监视器 d[][]
2、然后恢复原来的监视范围 a[][]
3、恢复后,把对应的位置置一,然后进行二维前缀和来统计 sum[][]
4、把小偷的活动范围面积求出来 与 前缀和 对比一下判断YES或NO
其实我是不知道怎么开辟二维数组的。。。
方法有两种:
用new来创建:
d = new int* [n+10];
a = new int* [n+10];
sum = new int* [n+10];
For(i,0,n+1){
d[i] = new int [m+10];
a[i] = new int [m+10];
sum[i] = new int [m+10];
}
用二维数组vector来开辟:
vector< vector<int> > d(n+10);
for(int i=0;i<n+5;i++){
d[i].resize(m+5);
}
vector< vector<int> > a(n+5);
for(int i=0;i<n+5;i++){
a[i].resize(m+5);
}
vector< vector<int> > sum(n+5);
for(int i=0;i<n+5;i++){
sum[i].resize(m+5);
}
差分数组:进行差分时候是:
d[x1][y1]++;
d[x2+1][y1]--;
d[x1][y2+1]--;
d[x2+1][y2+1]++;
恢复原数组,维护二维前缀和:
For(i,1,n){
For(j,1,m){
a[i][j] = a[i-1][j] + a[i][j-1] -a[i-1][j-1]+ d[i][j];
}
}
For(i,1,n){
For(j,1,m){
if( a[i][j] >=1 )
a[i][j]=1;
sum[i][j] = sum[i][j-1] + sum[i-1][j]
+ a[i][j] - sum[i-1][j-1];
}
}
【代码】:
#include<bits/stdc++.h>
#define For(i,L,R) for(int i=L;i<=R;i++)
using namespace std;
int n,m;
int p,q;
//int **d ,**sum,**a;
int main()
{
int x1,x2,y1,y2,S,T;
while(~scanf("%d%d",&n,&m)){
/*
d = new int* [n+10];
a = new int* [n+10];
sum = new int* [n+10];
For(i,0,n+1){
d[i] = new int [m+10];
a[i] = new int [m+10];
sum[i] = new int [m+10];
}
*/
vector< vector<int> > d(n+10);
for(int i=0;i<n+5;i++){
d[i].resize(m+5);
}
vector< vector<int> > a(n+5);
for(int i=0;i<n+5;i++){
a[i].resize(m+5);
}
vector< vector<int> > sum(n+5);
for(int i=0;i<n+5;i++){
sum[i].resize(m+5);
}
scanf("%d",&p);
while(p--){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
//x1++;y1++;x2++;y2++;
d[x1][y1]++;
d[x2+1][y1]--;
d[x1][y2+1]--;
d[x2+1][y2+1]++;
//printf("(%d %d) , (%d %d),(%d %d),(%d %d)\n",x1,y1,x2+1,y1,x1,y1+1,x2+1,y2+1);
}
For(i,1,n){
For(j,1,m){
a[i][j] = a[i-1][j] + a[i][j-1] -a[i-1][j-1]+ d[i][j];
}
}
For(i,1,n){
For(j,1,m){
if( a[i][j] >=1 )
a[i][j]=1;
sum[i][j] = sum[i][j-1] + sum[i-1][j]
+ a[i][j] - sum[i-1][j-1];
}
}
/*
puts("A");
For(i,0,n+1){
For(j,0,m+1){
printf("%d%c",a[i][j],j==m+1?'\n':' ');
}
}
puts("Sum");
For(i,0,n+1){
For(j,0,m+1){
printf("%d%c",sum[i][j],j==m+1?'\n':' ');
}
}
*/
scanf("%d",&q);
while(q--){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
//x1++;y1++;x2++;y2++;
S = (y2-y1+1) *(x2-x1+1);
T = sum[x2][y2] - sum[x2][y1-1]
- sum[x1-1][y2] + sum[x1-1][y1-1];
/*
printf("%d-%d-%d+%d\n",
sum[x2][y2],sum[x2][y1],
sum[x1-1][y2],sum[x1-1][y1-1]);
printf("%d %d\n",S,T);
*/
if(S==T){
printf("YES\n");
}else{
printf("NO\n");
}
}
}
return 0;
}