Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 803 Solved: 279
[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
这道题其实就是问是否存在某个
画出图像可以发现,这道题变成了【BZOJ 1007】水平可见直线。
首先按照斜率排序,斜率相同截距小的必然不可能。
当队列中已有两条直线时,如果第二三条直线的交点的横坐标小于第一二条直线交点的横坐标,那么第二条直线就不可能在最上面了(根据各自的管辖区域),从队列中删去。
一直这样做,最后剩下的直线就是在某些
但是这样还不够,如果两条直线的交点是
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define eps 1e-10
#define M 10005
using namespace std;
int n,q[M];
struct Car
{
int a,b,id;
}c[M];
bool cmp(Car a,Car b)
{
if (a.a==b.a) return a.b>b.b;
return a.a<b.a;
}
bool cmpp(int a,int b)
{
return c[a].id<c[b].id;
}
double Getinter(Car a,Car b)
{
return (double)(a.b-b.b)/(b.a-a.a);
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&c[i].b),c[i].id=i;
for (int i=1;i<=n;i++)
scanf("%d",&c[i].a);
sort(c+1,c+1+n,cmp);
c[0].a=-1;
int r=0;
for (int i=1;i<=n;i++)
{
if (c[i].a==c[i-1].a&&c[i].b<c[i-1].b) continue;
while (r>1&&Getinter(c[i],c[q[r]])<Getinter(c[q[r]],c[q[r-1]]))
r--;
q[++r]=i;
}
int l=1;
while (l<r&&Getinter(c[q[l]],c[q[l+1]])<-eps)
l++;
printf("%d\n",r-l+1);
sort(q+l,q+1+r,cmpp);
printf("%d",c[q[l]].id);
for (int i=l+1;i<=r;i++)
printf(" %d",c[q[i]].id);
printf("\n");
return 0;
}
WA是忘记把交点
原文地址:http://blog.csdn.net/regina8023/article/details/45126549