鏈接: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;
}