黑格覆盖(前缀和)
作者:互联网
黑格覆盖
输入
输入共 k+1 行:第 1 行为 5 个整数 M、N、m、n、k,其含义如题目所述。
接下来 k 行,每行 2 个整数,分别表示被涂成黑色的格子的行、列坐标。
输出
输出共 1 行,1 个整数,表示卡片一次性最多能覆盖的黑格子数。样例输入 Copy
3 5 2 2 3 1 1 2 2 3 5
样例输出 Copy
2
提示
根据样例数据所得到的涂完黑格的矩形和用于覆盖的矩形如下图所示:对于 40%的数据:m=n;
对于 100%的数据:M、N、m、n、k 均小于等于 1000,所有黑格不重复出现。
1 分别计算每行的黑格数的前缀和,和每列的黑格数的前缀和 2 找
m2=min(m1,m);
n2=min(n1,n);让卡片正放,暴力找最大值。根据容斥定理可知 ans=max(tu[i][j]-tu[i-m2][j]-tu[i][j-n2]+tu[i-m2][j-n2],ans);
3.将卡片倒放,再次暴力计算;
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 1e3+10; 4 5 int tu[N][N]= {0}; 6 int ans; 7 int main() 8 { 9 int m1,n1,m2,n2,k,m,n; 10 scanf("%d %d %d %d %d",&m1,&n1,&m,&n,&k); 11 12 for(int i=0,x,y;i<k;i++) 13 { 14 scanf("%d %d",&x,&y); 15 tu[x][y]=1; 16 } 17 18 for(int i=1; i<=m1; i++) 19 { 20 for(int j=1; j<=n1; j++) 21 { 22 tu[i][j]+=tu[i][j-1]; 23 } 24 25 } 26 27 for(int i=1; i<=m1; i++) 28 { 29 for(int j=1; j<=n1; j++) 30 tu[i][j]+=tu[i-1][j]; 31 } 32 33 m2=min(m1,m); 34 n2=min(n1,n); 35 for(int i=m2; i<=m1; i++) 36 { 37 for(int j=n2; j<=n1; j++) 38 { 39 ans=max(tu[i][j]-tu[i-m2][j]-tu[i][j-n2]+tu[i-m2][j-n2],ans); 40 } 41 } 42 43 44 m2=min(m1,n); 45 n2=min(n1,m); 46 for(int i=m2; i<=m1; i++) 47 { 48 for(int j=n2; j<=n1; j++) 49 { 50 ans=max(ans,tu[i][j]-tu[i-m2][j]-tu[i][j-n2]+tu[i-m2][j-n2]); 51 } 52 } 53 printf("%d\n",ans); 54 return 0; 55 }
标签:覆盖,卡片,int,tu,黑格,m2,n2,前缀 来源: https://www.cnblogs.com/sylvia1111/p/12247530.html