P3256 [JLOI2013] 赛车

题意

给出 \(n\) 辆车,每辆车有一个速度和初始位置,当一辆车的前方没有车时,称祂为领先的。问共有多少辆车曾经是领先的。
\(n\le1000\)

思路

对于每辆赛车,枚举其祂赛车,计算出祂超越所有祂前面的车的时间和被后面的车超越的时间,判断这两个时间之间是否有空隙。
注意:有可能有两辆车属性完全相同,需要进行特判。

代码

// Problem: P3256 [JLOI2013] 赛车
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3256
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
namespace IO{
    template<typename T>
    inline void read(T&x){
        x=0;char c=getchar();bool f=0;
        while(!isdigit(c)) c=='-'?f=1:0,c=getchar();
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
        f?x=-x:0;
    }
    template<typename T>
    inline void write(T x){
        if(x==0){putchar('0');return ;}
        x<0?x=-x,putchar('-'):0;short st[50],top=0;
        while(x) st[++top]=x%10,x/=10;
        while(top) putchar(st[top--]+'0');
    }
    inline void read(char&c){c=getchar();while(isspace(c)) c=getchar();}
    inline void write(char c){putchar(c);}
    void write(double x){printf("%lf",x);}
    inline void read(string&s){s.clear();char c;read(c);while(!isspace(c)&&~c) s+=c,c=getchar();}
    inline void write(string s){for(int i=0,len=s.size();i<len;i++) putchar(s[i]);}
    template<typename T>inline void write(T*x){while(*x) putchar(*(x++));}
    template<typename T,typename...T2> inline void read(T&x,T2&...y){read(x),read(y...);}
    template<typename T,typename...T2> inline void write(const T x,const T2...y){write(x),putchar(' '),write(y...),sizeof...(y)==1?putchar('\n'):0;}
}using namespace IO;
const int maxn=10010;
const double eps=1e-8;
struct node{
    int k,v,id;
    bool operator<(const node t)const{
        if(k==t.k) return v>t.v;
        return k>t.k;
    }
}a[maxn];
int n;
vector<int>ans;
signed main(){
    read(n);
    for(int i=1;i<=n;i++) read(a[i].k),a[i].id=i;
    for(int i=1;i<=n;i++) read(a[i].v);
    sort(a+1,a+1+n);
    int maxv=0,ltwin=0;
    for(int i=1;i<=n;i++){
        if(a[i].k==a[1].k){ans.push_back(a[i].id);maxv=max(maxv,a[i].v);ltwin=1;continue;}
        if(a[i].v==a[i-1].v&&a[i].k==a[i-1].k) if(ltwin){ans.push_back(a[i].id);ltwin=1;continue;}
        ltwin=0;
        if(maxv>=a[i].v) continue;
        maxv=a[i].v;
        double minn=INFINITY,maxx=0;
        for(int j=1;j<i;j++) maxx=max(maxx,(a[j].k-a[i].k)*1.0/(a[i].v-a[j].v));
        for(int j=i+1;j<=n;j++) if(a[j].v>a[i].v) minn=min(minn,(a[i].k-a[j].k)*1.0/(a[j].v-a[i].v));
        if(maxx<minn+eps) ans.push_back(a[i].id),ltwin=1;
    }
    write(ans.size()),write("\n");
    sort(ans.begin(),ans.end());
    for(int i:ans) write(i),write(" ");
    return 0;
}
posted @ 2026-08-10 15:22  Link-Cut_Trees  阅读(6)  评论(0)    收藏  举报