BZOJ3190: [JLOI2013]赛车

Posted ~Silent

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3190: [JLOI2013]赛车相关的知识,希望对你有一定的参考价值。

题目大意:

每辆赛车有自己的出发位置和速度,问有多少赛车在某个时刻处于第一的位置。

题解:

每辆赛车任意时刻的位置可以用一条直线来表示,按斜率排序依次加入,单调栈。

最后在栈中的就是最后的答案。

和BZOJ1007相似。

代码:

#include<cstdio>
#include<algorithm>
using namespace std;
int d[1000005];
struct node{
	int b,k,id;
}a[1000005],q[1000005];
bool cmp(node a,node b){
	return a.k<b.k || a.k==b.k && a.b<b.b;
}
bool cmp1(node a,node b){
	return a.id<b.id;
}
int main(){
	int n;
	scanf("%d",&n);
	for (int i=1; i<=n; i++)
		scanf("%d",&a[i].b);
	for (int i=1; i<=n; i++){
		scanf("%d",&a[i].k);
		a[i].id=i;
	}
	sort(a+1,a+n+1,cmp);
	int t=1;
	for (int i=2; i<=n; i++){
		if (a[i].k!=a[i-1].k || (a[i].k==a[i-1].k && a[i].b==a[i-1].b)) t++;
		a[t]=a[i];
	}
	n=t;
	q[1]=a[1];
	int top=1;
	d[1]=1;
	for (int i=2; i<=n; i++){
		while (top>=1 && a[i].b>q[top].b) top--;
		while (top>=2 && ((double)q[d[top]].b-q[top].b)/(q[top].k-q[d[top]].k)
						>((double)q[d[top]].b-a[i].b)/(a[i].k-q[d[top]].k)) top--;
		q[++top]=a[i];
		if (q[top].k==q[top-1].k) d[top]=d[top-1];
		else d[top]=top-1;
	}
	sort(q+1,q+top+1,cmp1);
	printf("%d\n",top);
	for (int i=1; i<top; i++)
		printf("%d ",q[i].id);
	printf("%d",q[top].id);
	return 0;
}

  

以上是关于BZOJ3190: [JLOI2013]赛车的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ3190[JLOI2013]赛车 单调栈+几何

BZOJ3190[JLOI2013]赛车

Bzoj4561 [JLoi2016]圆的异或并

BZOJ4561[JLoi2016]圆的异或并 扫描线

BZOJ3192: [JLOI2013]删除物品

BZOJ3191: [JLOI2013]卡牌游戏