思路:
定义一条鱼的前方为其运动方向,后方为其运动方向的反方向,则一条鱼能够被网捕捉到,当且仅当网的初始位置不在它的后方(即在前方或与它并排),因为网向四个方向扩展而鱼只向一个方向游且两者速度相同。
容易发现上下方向的鱼和左右方向的鱼是两个相互独立的系统。分别考虑水平和竖直方向的情况:贪心,可以证明只有网下在鱼某一条鱼并排的位置上才有可能得到最优解。对每个方向上的鱼的初始位置排序,枚举每个方向上的每条鱼,二分统计网下在与这条鱼并排的位置能网住多少同方向与反方向的鱼,取最大值。最后把水平方向上的最大值和竖直方向上的最大值相加得到结果。
调了一万年都只过 subtask 2……有没有大佬帮忙调一下qaq
#include<bits/stdc++.h>
#define rep1 for(int i=1;i<=n;i++)
using namespace std;
typedef long long LL;
const int M=100010;
int T,n;
int main()
{
cin>>T;
int tx,ty;
char ttd;
while(T--){
int l[M],r[M],u[M],d[M];//记录每个方向每条鱼的初始位置
l[0]=r[0]=u[0]=d[0]=0;
int tl=0,tr=0,tu=0,td=0;
scanf("%d",&n);
rep1{
scanf("%d%d %c",&tx,&ty,&ttd);
if(ttd=='R') r[++tr]=tx+1e9+10;//去除负数的情况
if(ttd=='L') l[++tl]=tx+1e9+10;
if(ttd=='U') u[++tu]=ty+1e9+10;
if(ttd=='D') d[++td]=ty+1e9+10;
}
int mh=0,mv=0; //mh记录水平方向最大值,mv记录竖直方向最大值
sort(r+1,r+1+tr); //排序
sort(l+1,l+1+tl);
sort(u+1,u+1+tu);
sort(d+1,d+1+td);
if(tl==0||tr==0) mh=max(tl,tr); //特判,防止有方向上一条鱼没有
else{
for(int i=1;i<=tl;i++){ //枚举每个方向每条鱼
int t;
if(r[1]>l[i]) t=1; //特判,防止二分卡bug
else t=upper_bound(r+1,r+1+tr,l[i])-r;
mh=max(mh,i+t-1);
}
for(int i=1;i<=tr;i++){
int t;
if(l[tl]<r[i]) t=tl+1;
else t=lower_bound(l+1,l+1+tl,r[i])-l;
mh=max(mh,i+tl-t+1);
}
}
if(tu==0||td==0) mv=max(tu,td);
else{
for(int i=1;i<=td;i++){
int t;
if(u[1]>d[i]) t=1;
else t=upper_bound(u+1,u+1+tu,d[i])-u;
mv=max(mv,i+t-1);
}
for(int i=1;i<=tu;i++){
int t;
if(d[td]<u[i]) t=td+1;
else t=lower_bound(d+1,d+1+td,u[i])-d;
mv=max(mv,i+td-t+1);
}
}
int mm=mh+mv;
printf("%d\n",mm);
}
return 0;
}