AtCoder Beginner Contest 176 E.Bomber

AtCoder Beginner Contest 176 E.Bomber

题目链接

AtCoder Beginner Contest 176 E.Bomber_第1张图片
比较简单的思维题,很明显,每一个点对行和列都有贡献值,我们只需找到最大的行贡献值和最大的列贡献值即可,这样成功了一大半,我们会发现行与列的交叉点如果有元素那么答案要减 1 1 1,那么我们可以记录所有等于最大贡献值的行号和所有最大贡献值的列号,判断是否存在交叉点即可 (很容易发现复杂度是 O ( n ) O(n) O(n) 的,而非 O ( n 2 ) O(n^2) O(n2)).这题惊人的 130 个点,还好一发过了,AC代码如下:

#include
using namespace std;
typedef long long ll;
const int N=3e5+5;
int h,w,m,x,y,r[N],c[N];
vector<int>v1,v2;
map<pair<int,int>,int>mp;
int main(){
    cin>>h>>w>>m;
    while(m--){
        cin>>x>>y;
        r[x]++,c[y]++;
        mp[{x,y}]=1;
    }
    int mx1=0,mx2=0;
    for(int i=1;i<=h;i++) mx1=max(mx1,r[i]);
    for(int i=1;i<=h;i++) if(r[i]==mx1) v1.push_back(i);
    for(int i=1;i<=w;i++) mx2=max(mx2,c[i]);
    for(int i=1;i<=w;i++) if(c[i]==mx2) v2.push_back(i);
    for(auto i:v1) for(auto j:v2) if(!mp[{i,j}]) {cout<<mx1+mx2;exit(0);}
    cout<<mx1+mx2-1;
}

你可能感兴趣的:(AtCoder,map,思维)