题目链接:https://atcoder.jp/contests/abc176/tasks/abc176_e
题意:给你一个 H ∗ W H*W H∗W的矩阵,矩阵里有 M M M个目标点,你要在这个个矩阵的任意位置(包括目标点)放一个炸弹,炸弹引爆后会摧毁炸弹同一行,同一列的所有目标点,问你最多可以炸几个目标点。
思路:一个朴实无华的题目,但给你一个相当恶心的数据范围,emmm。
所以这一题我们肯定不能“硬来”,得“智取”(doge)。
从直观上想,我们肯定是要找到所有行里面目标点最多得行,和目标点最多得列,那在这个行,这个列交点处放炸弹,肯定是能使得摧毁的目标点最多。但这就有另一个问题啦,那就是每一行,每一列目标点最多的,可能不止一个呀(个数分别用 n u m 1 num1 num1, n u m 2 num2 num2表示),难道我们用双层 f o r for for循环暴力发所有的组合全部跑一遍嘛?别想啦,出题人随便卡一卡,就能让你过不去…那我们可以回过来想一想,我们开始暴力找的目的是什么?是不是要找一下有没有一个交点不是目标点,那我们在这个交点埋炸弹,那答案是不是就是最大了呢?所以我们可以遍历所有的目标点,找出一共有多少个目标点是交点(用 n u m num num表示),这样如果 n u m 1 ∗ n u m 2 = = n u m num1 * num2 == num num1∗num2==num,那么答案是行列最大值相加减一就好啦(因为所有的交点都是目标点呀),这样这个问题就可以很快的AC啦。
AC代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <string>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define pii pair<int,int>
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define pd(x) printf("%d\n",x)
#define plld(x) printf("%lld\n",x)
#define rep(i,a,b) for(int i = (a) ; i <= (b) ; i++)
#define per(i,a,b) for(int i = (a) ; i >= (b) ; i--)
#define mem(a) memset(a,0,sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define fast_io ios::sync_with_stdio(false)
const LL INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const int maxn = 3e5 + 7;
map<int,int>cntx,cnty;
pii a[maxn];
int main() {
fast_io;
int n,m,num;
cin >> n >> m >> num;
int maxx = 0, maxy = 0;
rep(i,1,num) {
int x,y;
cin >> x >> y;
a[i].first = x, a[i].second = y;
cntx[x]++, cnty[y]++;
maxx = max(maxx, cntx[x]), maxy = max(maxy, cnty[y]);
}
int numx = 0, numy = 0;
for(auto temp: cntx) {
if(temp.second == maxx) numx++;
}
for(auto temp: cnty) {
if(temp.second == maxy) numy++;
}
int cnt = 0;
rep(i,1,num) {
if(cntx[a[i].first] == maxx && cnty[a[i].second] == maxy) cnt++;
}
if(numx * numy == cnt) cout << maxx + maxy - 1 << endl;
else cout << maxx + maxy << endl;
return 0;
}