题解 P2928【[USACO09HOL]牛的打手】

题目要求求一个运动的点 在 一堆运动的点的多少个的一定范围内
那么我们可以先转换为一个运动的点的一定范围内有其他运动的点中的多少个(求最多的时刻的个数)
那么聪明的我们都学过物理
物体的运动是相对的 所以我们让那个要找范围的运动点不动 所以就成了相对的 相对位置减一下 相对速度也减一下
所以这道题和牛绣有了异曲同工之妙

先算出交点 但是此时我们是以时间为未知量的 他不可能为负数吧!
(注意速度是有方向的)

然后我们可以推导三种情况

第一种 两端点都是正数

图片说明
那么两个点的时间就是方程解得的时间

第二种 两端点都是负数

图片说明
两个点都是反向延长线 答案此时不存在

第三种 两端点一正一负

图片说明
此时点在那个圆的中间 所以两端点时间一个为0 另一个为所求得的正值

所以我们用计算几何先求出点 之后再用一次扫描线就可以得到答案啦!

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<cmath>
#define LL long long
using namespace std;

struct node{
    int num;
    double v;
}e[100100];
int v[100100];
double r,bx,by,bvx,bvy;
int n,cnt;
double x,y,vx,vy;
inline int cmp(node a,node b)
{
    return a.v < b.v;
}
int main()
{
    scanf("%d%lf%lf%lf%lf%lf",&n,&r,&bx,&by,&bvx,&bvy);
    //敌动我动还能算吗? 
    //考虑位移是相对的  把速度改一下 位置也改一下 
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf%lf%lf",&x,&y,&vx,&vy);
        x-=bx;//3
        y-=by; //1
        vx-=bvx;//3
        vy-=bvy;//1

        // X= x + t*vx 
        // Y= y + t*vy
        // X*X+Y*Y=r*r 
        if(vx==0 && vy==0)
        {
            if(x*x+y*y<=r*r)
            {
                e[++cnt].v = 0;
                e[cnt].num = i; 
            }

            continue;
        }
        // x*x + vx*vx*t*t + 2*x*vx*t +
        // y*y + vy*vy*t*t + 2*y*vy*t = r*r
        // (vx*vx+vy*vy)*t*t+ (2*x*vx+2*y*vy)*t + x*x+y*y-r*r =0
        double A=vx*vx+vy*vy;
        double B=2*x*vx+2*y*vy;
        double C=x*x+y*y-r*r;
        double delta=B*B-4*A*C;
//        cout<<x<<" "<<y<<" "<<vx<<" "<<vy<<" "<<A<<" "<<B<<" "<<C<<" "<<delta<<" YYYY "<<endl; 
        if(A<=1e-8)
        {
            if(C>0) continue;
            e[++cnt].v = 0;
            e[cnt].num = i;
            e[++cnt].v = 1e9;
            e[cnt].num = i;  
            continue;
        }
        else if(delta<0) continue;
        else
        {
            if((-B-sqrt(delta))*1.0/(2*A)<0 && (-B+sqrt(delta))*1.0/(2*A)<0) continue;
                e[++cnt].v = (-B-sqrt(delta))*1.0/(2*A);
                e[cnt].num = i;
                e[++cnt].v = (-B+sqrt(delta))*1.0/(2*A);
                e[cnt].num = i;
        }
    }
    sort(e+1,e+1+cnt,cmp);
    LL ans=0,tmp=0;
    for(int i=1;i<=cnt;i++)
    {
//        cout<<e[i].num <<"   "<<e[i].v<<" TYTYTYT "<<endl;
        int num=e[i].num;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
        if(v[num]==0)
        {
            tmp++;
            v[num]=1;
        }
        else
        {
            tmp--;
        }
        if(tmp>ans) ans=tmp;
    }
    printf("%lld",ans);
}
全部评论

相关推荐

行云流水1971:这份实习简历的优化建议: 结构清晰化:拆分 “校园经历”“实习经历” 板块(当前内容混杂),按 “实习→校园→技能” 逻辑排版,求职意向明确为具体岗位(如 “市场 / 运营实习生”)。 经历具象化:现有描述偏流程,需补充 “动作 + 数据”,比如校园活动 “负责宣传” 可加 “运营公众号发布 5 篇推文,阅读量超 2000+,带动 300 + 人参与”;实习内容补充 “协助完成 XX 任务,效率提升 X%”。 岗位匹配度:锚定目标岗位能力,比如申请运营岗,突出 “内容编辑、活动执行” 相关动作;申请市场岗,强化 “资源对接、数据统计” 细节。 信息精简:删减冗余表述(如重复的 “负责”),用短句分点,比如 “策划校园招聘会:联系 10 + 企业,组织 200 + 学生参与,到场率达 85%”。 技能落地:将 “Office、PS” 绑定经历,比如 “用 Excel 整理活动数据,输出 3 份分析表;用 PS 设计 2 张活动海报”,避免技能单独罗列。 优化后需强化 “经历 - 能力 - 岗位需求” 的关联,让实习 / 校园经历的价值更直观。 若需要进一步优化服务,私信
实习,投递多份简历没人回...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务