LuoguP1369 矩形 前缀和

分别预处理每行每列前缀合,然后枚举两顶点坐标即可。读取线段上值时要注意去重!

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 
 5 const int Maxn = 110;
 6 int xs[Maxn][Maxn],ys[Maxn][Maxn],g[Maxn][Maxn];
 7 int n,x,y,ans;
 8 
 9 int tot(int x1,int y1,int x2,int y2){
10     if(x1 == x2)return ys[x2][y2]-ys[x2][y1-1];
11     if(y1 == y2)return xs[x2][y2]-xs[x1-1][y1];
12     return xs[x2][y1]-xs[x1-1][y1]+xs[x2][y2]-xs[x1-1][y2]
13         +ys[x1][y2-1]-ys[x1][y1]+ys[x2][y2-1]-ys[x2][y1];
14 }
15 
16 void print(int a[110][110]){
17     for(int i = 1;i <= 11;i++){
18         for(int j = 1;j <= 11;j++)printf("%d ",a[i][j]);
19         putchar('
');
20     }
21     putchar('
');
22 }
23 
24 int main(){
25     cin >> n;
26     for(int i = 1;i <= n;i++){
27         cin >> x >> y;
28         g[x][y] = 1;
29     }
30     for(int i = 1;i <= 100;i++){
31         ys[i][0] = xs[0][i] = 0;
32         for(int j = 1;j <= 100;j++){
33             ys[i][j] = ys[i][j-1]+g[i][j];
34             xs[j][i] = xs[j-1][i]+g[j][i];
35         }
36     }
37     for(int x1 = 1;x1 <= 100;x1++)
38         for(int y1 = 1;y1 <= 100;y1++)
39             for(int x2 = x1;x2 <= 100;x2++)
40                 for(int y2 = y1;y2 <= 100;y2++)
41                     ans = max(ans,tot(x1,y1,x2,y2));
42     cout << ans;
43 return 0;
44 }
View Code

 ps:好像还可以用一般的二维前缀和外层减里层处理。。

原文地址:https://www.cnblogs.com/Wangsheng5/p/11676404.html