原题见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-8
using 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;
}