[AtCoder] Beginner Contest 176 E - Bomber
Solutions Atcoder 贪心
Lastmod: 2020-09-18 周五 19:12:45

E - Bomber

题目大意

给出一个 $H \times W$ 的矩阵,上面有 $M$ 个点,选出一行一列使得覆盖到的点最多。问最多是多少。

其中 $H,W,M <= 3 \times 10^5$

简要题解

注意到一定会贪心的选某个数量最多的行和列。设其行列数量分别 $mx$,$my$,则答案只可能是 $mx + my$ 或 $mx + my - 1$。则只需验证所有数量为 $mx$ 的行和所有数量为 $my$ 的列是否有点,这里注意到最多只会有 $M$ 个点,因此如果行和列交点特别多的情况,必然在前 $M+1$ 次 $check$ 会有一次是不存在点的,算法就会终止。

复杂度

$T$:$O(H+W+MlogM)$ 这里可以使用 hash 进一步降低复杂度,不过 set 已经足够快了

$S$:$O(H+W+M)$

代码实现

#include <bits/stdc++.h>
using namespace std;

typedef pair<int,int> PII;
const int M=3e5+5;
int cntx[M],cnty[M];

set<PII> se;

int main()
{
    int h,w,m; scanf("%d%d%d",&h,&w,&m);
    int x,y;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&x,&y);
        cntx[x]++;
        cnty[y]++;
        se.emplace(x,y);
    }
    int mx=0,my=0;
    for(int i=1;i<=h;i++)
        mx=max(mx,cntx[i]);
    for(int i=1;i<=w;i++)
        my=max(my,cnty[i]);
    vector<int> vx,vy;
    for(int i=1;i<=h;i++)
        if(cntx[i]==mx) vx.push_back(i);
    for(int i=1;i<=w;i++)
        if(cnty[i]==my) vy.push_back(i);
    int f=0;
    int ans=mx+my-1;
    for(int i:vx)
    {
        for(int j:vy)
        {
            if(!se.count({i,j}))
            {
                ans=mx+my;
                f=1;
                break;
            }
        }
        if(f) break;
    }
    printf("%d\n",ans);
    return 0;
}
Prev: [LeetCode] 1575. Count All Possible Routes
Next: 《汇编语言》 笔记 第 1 章 基础知识