链接:https://ac.nowcoder.com/acm/contest/332/E
来源:牛客网
题目描述
有一个沿海地区,可以看作有n行m列的城市,第i行第j列的城市海拔为h[i][j]。
由于沿海,所以这个地区经常会发生海啸。
海啸发生时,部分城市会被淹没,具体来说,海水高度会达到d,因此海拔低于d的城市都会被淹没。
现在有q次询问,每次问你一个矩形区域中,有多少城市不会被淹没。
由于沿海,所以这个地区经常会发生海啸。
海啸发生时,部分城市会被淹没,具体来说,海水高度会达到d,因此海拔低于d的城市都会被淹没。
现在有q次询问,每次问你一个矩形区域中,有多少城市不会被淹没。
输入描述:
第一行三个整数n,m,d,具体含义见题目描述。
接下来n行,每行m个整数,其中第i行第j列的整数为h[i][j],具体含义见题目描述。
第n+2行一个整数q,表示询问数。
接下来q行,每行四个整数a,b,x,y,
表示询问从第a行第b列到第x行第y列的矩形地区中,有多少地区不会被淹没。
即有多少个i,j,满足 a≤i≤x,b≤j≤ya≤i≤x,b≤j≤y ,且 h[i][j]≥dh[i][j]≥d 。
输出描述:
共q行,第i行一个整数,表示第i个询问的答案。
示例1
输入
3 3 3 1 2 3 2 1 5 4 3 2 2 1 2 2 3 2 1 3 3
输出
2 3
备注:
1≤n×m≤1061≤n×m≤106
1≤q≤1051≤q≤105
0≤d,h[i][j]≤1090≤d,h[i][j]≤109
1≤a≤x≤n,1≤b≤y≤m
分析:
1.只给出矩阵n*m<=1e6,行列大小不定,可以用邻接表解决
2.询问数量过大,不可能暴力,可以用前缀和解决
3.第a行第b列到第x行第y列的矩形地区中,有多少地区不会被淹没,这是个坑,前缀和需要表示成矩阵形状的前缀和
4.边界情况需要考虑,防止数组越界
显然:ans=vec[x][y]+vec[a-1][b-1]-vec[x][b-1]-vec[a-1][y];
#include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> #include<string> #include<vector> #include<iostream> #include<cstring> #define inf 0x3f3f3f3f using namespace std; #define ll long long int n,m,d,h,q,a,b,x,y; int main() { scanf("%d%d%d",&n,&m,&d); vector<int>vec[n+10];///前缀和数组 for(int i=0;i<=m;i++) vec[0].push_back(0); for(int i=0;i<=n;i++) vec[i].push_back(0); for(int i=1;i<=n;i++) { int num=0; for(int j=1;j<=m;j++) { scanf("%d",&h); if(h>=d) { num++; vec[i].push_back(num+vec[i-1][j]); } else vec[i].push_back(num+vec[i-1][j]);///每一行当前的没有被淹数 + 上一行该列的矩阵和,形成矩阵前缀和 } } scanf("%d",&q); while(q--) { scanf("%d%d%d%d",&a,&b,&x,&y); printf("%d ",vec[x][y]+vec[a-1][b-1]-vec[x][b-1]-vec[a-1][y]); } return 0; }