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