CodeForces 832C. Strange Radiation 二分

Portal

The meaning of problems

In the interval \ ([^ 6 0,10] \) there are \ (n \) personal, everyone has a position at the start, direction and speed \ (v_i \) , move in the direction of the face,
you can put a bomb in the interval in an arbitrary integer position, after launching a bomb exploded speed on both sides were \ (s \) wave
after wave and the same person to contact to the wave speed turn \ (v_i + s \)
how much to ask at least there are people around the interval of time after arrival.

Thinking

This minimum legal answer questions asked should go on half think
if known time \ (t \) , the question is how to verify its legitimacy
can first decide on a direction, then for every person in this direction, if he calculated want to \ (t \) within reach the boundary,
the bomb should be placed in position, this position is clearly an interval, and then find the corresponding section of each individual and set
the same way in the other direction to obtain the corresponding bombs can be placed in the interval
if this two intervals intersect, then \ (t \) on legitimate,
as to how to calculate each of the corresponding interval, it can only calculate the pen

Code

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
const int MAXM=1e6+10;
const int L=1e6;
int n,s,suml[MAXM],sumr[MAXM];
struct Person{
    int x,v,dir;
}p[MAXN];

bool check(double t){
    memset(suml,0,sizeof(suml));
    memset(sumr,0,sizeof(sumr));
    for(int i=1;i<=n;i++){
        int x=p[i].x,v=p[i].v,dir=p[i].dir;
        if(dir==1){
            if(t*v>=x+1e-8) {suml[0]++;continue;}
            if(t*(s+v)<x-1e-8) continue;
            double dis=(t*(s-v)*(s+v)+1.0*v*x-1.0*s*x)/s;
            suml[x]++;suml[min((int)dis+x,L)+1]--;
        }
        else{
            if(t*v>=L-x+1e-8) {sumr[0]++;continue;}
            if(t*(s+v)<L-x-1e-8) continue;
            double dis=(t*(s-v)*(s+v)+1.0*(L-x)*(v-s))/s;
            sumr[max(x-(int)dis,0)]++;sumr[x+1]--;
        }
    }
    for(int i=1;i<=1e6;i++) suml[i]+=suml[i-1],sumr[i]+=sumr[i-1];
    for(int i=0;i<=1e6;i++) if(suml[i]&&sumr[i]) return true;
    return false;
}

int main(){
    scanf("%d%d",&n,&s);
    for(int i=1;i<=n;i++)
        scanf("%d%d%d",&p[i].x,&p[i].v,&p[i].dir);
    double l=0,r=1e6;
    while(r-l>1e-8){
        double mid=(r+l)/2;
        if(check(mid)) r=mid;
        else l=mid;
    }
    printf("%.7lf",l);
    return 0;
}

Guess you like

Origin www.cnblogs.com/BakaCirno/p/12164544.html