bzoj2765: [JLOI2010]铁人双项比赛
2017-05-10 08:12
190 查看
题解
这题思路好像不是那么明显。你可以列出每个人的用时关于k的式子
ti=(1v1−1v2)k+sv2
那么你就要选择一个恰当的k使得tn最小且次小值与它的差最大。
那就是说有若干条直线,你要找一个横坐标使得第n条直线在最下方,且次小的直线与它的差值最小。
显然这样的横坐标肯定是某个交点的横坐标。因此我们可以求出所有的交点,然后每个交点检验一下它是不是在最下方的交点,然后再更新下答案就好了。
这样是O(n3)
代码
//计算几何 #include <cstdio> #include <algorithm> #include <cmath> #define maxn 233 #define eps 1e-8 using namespace std; int N, tot; double k[maxn], b[maxn], dy=-1e100, s, dx; struct point{double x, y;}pt[maxn*maxn]; point jiao(int l1, int l2) { point pt; if(fabs(k[l1]-k[l2])<eps)return (point){-1,-1}; pt.x=(b[l1]-b[l2])/(k[l2]-k[l1]); pt.y=pt.x*k[l1]+b[l1]; return pt; } void input() { int i; double v1, v2; scanf("%lf%d",&s,&N); for(i=1;i<=N;i++) { scanf("%lf%lf",&v1,&v2); k[i]=1/v1-1/v2; b[i]=s/v2; } } void solve() { int i, j; double t, x, y; for(i=1;i<=tot;i++) { x=pt[i].x, y=pt[i].y; if(x<0 or x>s)continue; for(j=1;j<N;j++)if(k[j]*x+b[j]<y-eps)break; if(j==N) if(y-k *x-b >dy)dy=y-k *x-b , dx=x; } } int main() { int i, j; input(); for(i=1;i<N;i++)for(j=i+1;j<N;j++)pt[++tot]=jiao(i,j); for(i=1;i<=N;i++)pt[++tot]=(point){0,b[i]}, pt[++tot]=(point){s,k[i]*s+b[i]}; solve(); if(dy<-eps)printf("NO"); else printf("%.2lf %.2lf %d",dx,s-dx,(int)(dy*3600+0.5)); return 0; }
相关文章推荐
- bzoj2765[JLOI2010]铁人双项比赛
- 【BZOJ】【2765】【JLOI2010】铁人双项比赛
- bzoj 2765: [JLOI2010]铁人双项比赛 (计算几何)
- [BZOJ2756][JLOI2010]铁人双项比赛(半平面交+三分法)
- bzoj-2765 铁人双项比赛
- bzoj2765 铁人双项比赛
- bzoj2765 [JLOI2010]铁人双项比赛
- bzoj2768[JLOI2010]冠军调查
- bzoj 2768: [JLOI2010]冠军调查
- 【bzoj2768】【JLOI2010】【冠军调查】【最小割】
- bzoj 2768: [JLOI2010]冠军调查 最小割
- BZOJ 2768: [JLOI2010]冠军调查 最小割
- BZOJ 2768 [JLOI2010]冠军调查
- 【bzoj2768/bzoj1934】[JLOI2010]冠军调查/[Shoi2007]Vote 善意的投票 最小割
- bzoj 2768: [JLOI2010]冠军调查
- 【BZOJ2768】[JLOI2010]冠军调查/【BZOJ1934】[Shoi2007]Vote 善意的投票 最小割
- BZOJ [JLOI2010]冠军调查
- bzoj 2768: [JLOI2010]冠军调查
- [BZOJ2768][JLOI2010]冠军调查(最小割)
- bzoj2768 [JLOI2010]冠军调查(最小割,和bzoj1934一模一样)