bzoj3190[JLOI2013]赛车

bzoj3190[JLOI2013]赛车

题意:

赛场上一共有N辆车。赛道是一条无限长的直线。在这个比赛过程中,如果一辆赛车曾经处于领跑位置的话(即没有其他的赛车跑在他的前面),这辆赛车最后就可以得奖。已知所有赛车的起始位置(离起跑线距离)和速度,求出那些赛车将会得奖。

题解:

有人说是类似线性规划,用半平面交,反正我不会,数学考试是线性规划也错得一塌糊涂QAQ。

黄学长用的是维护斜率的方法,按照斜率排个序,依次插入一个单调栈,如果栈顶不满足XX条件(说不清楚,画个图)就弹掉,最后留在栈里的就是答案。

代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #define inc(i,j,k) for(int i=j;i<=k;i++)
 5 #define eps 1e-8
 6 using namespace std;
 7 
 8 struct nd{
 9     int s,v,id;
10     bool operator < (const nd& a)const{
11         if(v!=a.v)return v<a.v; return s<a.s;
12     }
13 };
14 double solve(nd a,nd b){
15     return (double)(a.s-b.s)/(double)(b.v-a.v);
16 }
17 nd nds[20000],s[20000]; int ans[20000],n,tp;
18 int main(){
19     scanf("%d",&n); inc(i,1,n)scanf("%d",&nds[i].s),nds[i].id=i; inc(i,1,n)scanf("%d",&nds[i].v); sort(nds+1,nds+1+n);
20     tp=1;s[tp]=nds[1];ans[tp]=nds[1].id;
21     inc(i,2,n){
22         while(tp>=1&&solve(s[tp],nds[i])<-eps)tp--;
23         while(tp>=2&&solve(s[tp-1],s[tp])>solve(s[tp],nds[i]))tp--;
24         s[++tp]=nds[i]; ans[tp]=nds[i].id;
25     }
26     sort(ans+1,ans+1+tp); printf("%d\n",tp);
27     inc(i,1,tp){
28         i==tp?printf("%d",ans[i]):printf("%d ",ans[i]);
29     }
30     return 0;
31 }

 

20160407

posted @ 2016-07-21 21:06  YuanZiming  阅读(420)  评论(0编辑  收藏  举报