每辆赛车有起始位置和速度,问哪些赛车在比赛过程中领先。
简直立了flag。。精度问题卡死我了。。
由s-t图像可得使用半平面交。
注意会有2两车的参数完全相同。要去重的时候把id也记录下来。
而且可以两辆车同时领先。
有些的斜率太相近。。结果atan2结果一样算法跪了。
我的算法应该是必开long double的。
下次用反三角一定要开long double。。。。。。
调了好久才发现这个问题。。
而且这道题好像是全字符比较?文尾有空格什么的会PE。
不过这道题也就我这么作死套半平面交模板233。
#include <cstdio>
#include <algorithm>
#include <list>
#include <cmath>
#define FOR(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int N = 50001;
typedef long double ld;
struct Point {
ld x, y;
Point(){}
Point(ld _x, ld _y) : x(_x), y(_y) {}
Point operator +(const Point &b) const { return Point(x + b.x, y + b.y); }
Point operator -(const Point &b) const { return Point(x - b.x, y - b.y); }
double operator *(const Point &b) const { return x * b.y - y * b.x; }
Point operator *(double b) const { return Point(b * x, b * y); }
bool operator ==(const Point &b) const { return x == b.x && y == b.y; }
} p[N];
struct Line {
Point x, v;
ld ang;
list<int> id;
Line(){}
Line(const Point &_x, const Point &_v) : x(_x), v(_v), ang(atan2(_v.y, _v.x)) { }
bool operator <(const Line &b) const {
if (ang == b.ang) return v * (b.x - x) < 0;
return ang < b.ang;
}
bool operator ==(const Line &b) const { return ang == b.ang; }
Point intersection(const Line &b) {
Point u = x - b.x;
ld t = (b.v * u) / (v * b.v);
return x + v * t;
}
} l[N], q[N];
bool right(const Point &p, const Line &l) {
return l.v * (p - l.x) < 0;
}
int main() {
static int ans[N], k[N], v[N];
int n, i, j, f = 1, r = 0, m = 0;
scanf("%d", &n);
FOR(i,1,n) scanf("%d", &k[i]);
FOR(i,1,n) scanf("%d", &v[i]);
FOR(i,1,n) l[i] = Line(Point(0, k[i]), Point(1, v[i])), l[i].id.push_back(i);
l[++n] = Line(Point(0, 0), Point(0, -1));
sort(l + 1, l + n + 1);
q[++r] = l[1]; q[++r] = l[2];
for (i = 3; i <= n; i++) {
if (l[i].v == q[r].v) {
if (l[i].x.y == q[r].x.y)
q[r].id.merge(l[i].id);
} else {
while (f < r && right(q[r].intersection(q[r - 1]), l[i])) r--;
q[++r] = l[i];
}
}
for (i = f + 1; i <= r; i++)
for (list<int>::iterator it = q[i].id.begin(); it != q[i].id.end(); it++) {
ans[++m] = *it;
}
sort(ans + 1, ans + m + 1);
printf("%d\n", m);
for (i = 1; i <= m; i++) {
printf("%d", ans[i]);
if (i < m) putchar(' ');
}
return 0;
}
3190: [JLOI2013]赛车
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1166 Solved: 373
[ Submit][ Status][ Discuss]
Description
这里有一辆赛车比赛正在进行,赛场上一共有N辆车,分别称为个g1,g2……gn。赛道是一条无限长的直线。最初,gi位于距离起跑线前进ki的位置。比赛开始后,车辆gi将会以vi单位每秒的恒定速度行驶。在这个比赛过程中,如果一辆赛车曾经处于领跑位置的话(即没有其他的赛车跑在他的前面),这辆赛车最后就可以得奖,而且比赛过程中不用担心相撞的问题。现在给出所有赛车的起始位置和速度,你的任务就是算出那些赛车将会得奖。
Input
第一行有一个正整数N表示赛车的个数。
接下来一行给出N个整数,按顺序给出N辆赛车的起始位置。
再接下来一行给出N个整数,按顺序给出N辆赛车的恒定速度。
Output
输出包括两行,第一行为获奖的赛车个数。
第二行按从小到大的顺序输出获奖赛车的编号,编号之间用空格隔开,注意最后一个编号后面不要加空格。
Sample Input
4
1 1 0 0
15 16 10 20
Sample Output
3
1 2 4
HINT
对于100%的数据N<=10000, 0<=ki<=10^9, 0<=vi<=10^9