黑格覆盖(前缀和)

时光总嘲笑我的痴心妄想 提交于 2020-02-01 09:23:49

黑格覆盖


 
在一张由 M * N 个小正方形格子组成的矩形纸张上,有 k 个格子被涂成了黑色。给你一张由 m * n 个同样小正方形组成的矩形卡片,请问该卡片最多能一次性覆盖多少个黑格子?

输入

输入共 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 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!