Codeforces 589D Boulevard 线段相交

来源:互联网 发布:中国的阿拉伯之春 知乎 编辑:程序博客网 时间:2024/06/04 20:52

原题见CF 589D

有n个人在x轴上运动,每个人从a点走到b点,出发时间为c,速度为1。其余时间就在x轴上消失。问每个人与另外的多少个人相遇。

这个问题可以抽象为几何问题。
首先可以作出时间-位置变化曲线,即线段,且两端点分别为(c, a), (c+fabs(a-b), b)。当两线段相交,即在同时刻同位置出现,算相遇了。

附code

#include <bits/stdc++.h>#define N 1005#define eps 1e-8using namespace std;int ans[N];struct point{    double x, y;    point(){}    point(double x, double y):x(x), y(y){}    point operator - (const point &b) const{        point c;        c.x = x-b.x, c.y = y-b.y;        return c;    }    void pr(){        printf("%.2lf %.2lf\n", x, y);    }}p[2*N];double cross(point P, point Q){    return P.x*Q.y - P.y*Q.x;}int det(double x){    if(fabs(x) < eps) return 0;    return x > 0 ? 1 : -1;}bool ha(point A, point B, point C, point D){    int sa = det(cross(A-C, D-C));    int sb = det(cross(B-C, D-C));    if(sa*sb > 0) return false;    return true;}bool check(point A, point B, point C, point D){    if((max(A.x, B.x) >= min(C.x, D.x))&&        (max(A.y, B.y) >= min(C.y, D.y))&&        (max(C.x, D.x) >= min(A.x, B.x))&&        (max(C.y, D.y) >= min(A.y, B.y))&&        ha(A, B, C, D) && ha(C, D, A, B))        return true;    return false;}int main(){    int n;    while(~scanf("%d", &n))    {        memset(ans, 0, sizeof(ans));        for(int i = 0;i < n;i++)        {            double t, a, b;            scanf("%lf%lf%lf", &t, &a, &b);            p[2*i] = point(t, a);            p[2*i+1] = point(t+fabs(a-b), b);        }        for(int i = 0;i < n;i++)            for(int j = i+1;j < n;j++)                if(check(p[2*i], p[2*i+1], p[2*j], p[2*j+1]))                {                       ans[i]++; ans[j]++;                }        for(int i = 0;i < n;i++)            printf("%d%c", ans[i], " \n"[i==n-1]);    }    return 0;}
0 0
原创粉丝点击