【bzoj 3190】: [JLOI2013]赛车 暴力

**
**
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1332 Solved: 425
[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

题解
1.
[按节距排序] 第一种 1后暴力算焦点x坐标,b大且焦点大的可减掉;之后无焦点
2.【bzoj 3190】: [JLOI2013]赛车 暴力_第1张图片
第二种如图,1-3枚举;;

好像还有半平面交的正解;

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
struct car
{
int id,k,v;
}c[10005];
int n,k[10005],v[10005],ans[10005],num=0;
int cmp(car a,car b)
{
if (a.v!=b.v) return a.v>b.v;
else return a.k<b.k;
}
int main()
{
// freopen("race.in","r",stdin);
// freopen("race.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
c[i].id=i;
cin>>c[i].k;
}
for(int i=1;i<=n;i++)
cin>>c[i].v;
sort(c+1,c+1+n,cmp);
int now=1;
while (now<=n)
{
ans[++num]=c[now].id;
double mint=0x7fffffff;
int nex=n+1;
for (int i=now+1;i<=n;i++)
{
if (c[i].v==c[now].v && c[i].k==c[now].k)
{
nex=i;
break;
}
else if (c[i].v<=c[now].v) continue;
double t=(double)(c[now].k-c[i].k)/(double)(c[i].v-c[now].v);
if (t<mint)
{
mint=t;
nex=i;
}
}
now=nex;
}
sort(ans+1,ans+1+num);
printf("%d\n",num);
for (int i=1;i<num;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[num]);
}  

你可能感兴趣的:(【bzoj 3190】: [JLOI2013]赛车 暴力)