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('\n'); 20 } 21 putchar('\n'); 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 }
ps:好像还可以用一般的二维前缀和外层减里层处理。。