码迷,mamicode.com
首页 > 其他好文 > 详细

【BZOJ 3190】 [JLOI2013]赛车

时间:2015-04-19 10:11:41      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:bzoj   oi   计算几何   单调栈   

3190: [JLOI2013]赛车

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

这道题其实就是问是否存在某个x使得vix+ki不小于任何一个vjx+kj

画出图像可以发现,这道题变成了【BZOJ 1007】水平可见直线

首先按照斜率排序,斜率相同截距小的必然不可能。

当队列中已有两条直线时,如果第二三条直线的交点的横坐标小于第一二条直线交点的横坐标,那么第二条直线就不可能在最上面了(根据各自的管辖区域),从队列中删去。

一直这样做,最后剩下的直线就是在某些x下在所有直线的最上面。

但是这样还不够,如果两条直线的交点是0的,那么斜率较小的那一条只有在x<0的时候才能在其他直线上面,不合题意,因此最后在队列从左开始扫,把交点<0的剔除。

#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是忘记把交点<0的剔除了。

【BZOJ 3190】 [JLOI2013]赛车

标签:bzoj   oi   计算几何   单调栈   

原文地址:http://blog.csdn.net/regina8023/article/details/45126549

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!