链接:https://ac.nowcoder.com/acm/contest/890/F
题意:n个气球,横着打3枪竖着打3枪(横着打的相邻两枪之间的间隔和竖着打的相邻两枪间隔都要等于r。)。求最多能打多少气球。同一个位置可能有多个气球。
思路:求出横着打和竖着打所有结果,按个数从大到小排序,最大值肯定就从前几大的打法中组合出,这里我取的前4大,总共16种情况。cometoj有道题和这道有类似的思想,可惜比赛的时候没想起来。太菜了。。。。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 3e5+10;
int a,b,n,r,x[N],y[N],maxx,maxy,tx,ty;
struct node
{
int pos,num;
}numx[N],numy[N];
map<int,map<int,int> > mp;
bool cmp (node a,node b)
{
if(a.num==b.num)
return a.pos<b.pos;
else return a.num>b.num;
}
int main(void)
{
scanf("%d%d",&n,&r);
maxx=maxy=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
x[a]++; y[b]++;
if(a>maxx) maxx=a;
if(b>maxy) maxy=b;
mp[a][b]++;
}
for(int i=0;i<=maxx;i++)
numx[i].pos=i,numx[i].num=x[i]+x[i+r]+x[i+2*r];
for(int i=0;i<=maxy;i++)
numy[i].pos=i,numy[i].num=y[i]+y[i+r]+y[i+2*r];
sort(numx,numx+maxx+1,cmp);
sort(numy,numy+maxy+1,cmp);
int ans=0,temp;
for(int i=0;i<=min(3,maxx);i++)
{
for(int j=0;j<=min(3,maxy);j++)
{
tx=numx[i].pos;
ty=numy[j].pos;
temp=numx[i].num+numy[j].num;
for(int ii=0;ii<=2;ii++)
for(int jj=0;jj<=2;jj++)
{
temp-=mp[tx+ii*r][ty+jj*r];
}
ans=max(ans,temp);
}
}
printf("%d\n",ans);
return 0;
}