题解:AT_abc176_e [ABC176E] Bomber
分析
我们可以用 \(hf\) 和 \(wf\) 分别储存每行的目标数及每列的目标数。
然后我们可以贪心:
若想摧毁最多的目标,则选定的位置所在的行是所有行中目标最多的,所在的列是所有列中目标最多的 (感性理解一下) 。
但是,选定的位置也可能有一个目标。在统计摧毁的目标数时,该目标被算了两次。所以要将该目标被多算的那次减掉。
所以我们可以枚举每个满足条件的位置,然后看是否有一个位置上没有炸弹。
若是,则输出 \(maxh+maxw\) 。
否则,输出 \(maxh+maxw-1\) 。
那么代码如下(这里用的是时间复杂度更小的unordered_map
):
#include<bits/stdc++.h>
#define int long long
#define fd(i,a,b) for(int i=a;i<=b;i=-~i)
using namespace std;
int h,w,m,hf[300100],wf[300100];
int ans=1,hi,wi,maxh,maxw,cnth,cntw;
int sumh[300100],sumw[300100];
unordered_map < int,unordered_map<int,int> > mp;
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>h>>w>>m;
fd(i,1,m)
{
cin>>hi>>wi;
hf[hi]++;wf[wi]++;
maxh=max(hf[hi],maxh);
maxw=max(wf[wi],maxw);
mp[hi][wi]++;
}
fd(i,1,h)
{
if(hf[i]==maxh) sumh[++cnth]=i;
}
fd(i,1,w)
{
if(wf[i]==maxw) sumw[++cntw]=i;
}
fd(i,1,cnth)
{
fd(j,1,cntw)
{
if(!mp[sumh[i]][sumw[j]])
{
ans=0;
break;
}
}
}
cout<<maxh+maxw-ans;
return 0;
}
感谢观看
本文来自博客园,作者:whrwlx,转载请注明原文链接:https://www.cnblogs.com/whrwlx/p/18111054