HDU
来源:互联网 发布:c语言计算排列组合 编辑:程序博客网 时间:2024/06/05 17:19
点我看题
题意:n个人参加一个接力赛,跑道长度为L,每个人根据跑步时的心情的不同速度也不一样,bad mood时速度为s,good mood时速度为t,每个人至少跑d米,当满足所有人都在badmood下且花费的时间不超过w的情况下,如果所有人都以goodmood跑,至少要花费多少时间。
分析:参考的HDU 4128 Running relay (贪心+凸包优化)这篇博客
参考代码:
#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<iostream>using namespace std;#define eps 1e-6const int maxn = 1e4+10;int n;double d,len,w;int sgn( double x){ if( x > eps)//x>0 return 1; else if( x < -eps)//x==0 return -1; else//x<0 return 0;}//x:s,y:t//用点的横纵坐标来记录runner的速度值struct Point{ double x,y; Point(){} Point( double xx, double yy) { x = xx; y = yy; } Point operator - ( const Point &p)const { return Point(x-p.x,y-p.y); } double operator ^ ( const Point &p)const { return x*p.y-p.x*y; } bool operator < ( const Point &p)const { return sgn(x-p.x) < 0 || (sgn(x-p.x) == 0 && sgn(y-p.y) < 0); }}p[maxn],tmp[maxn];double xmult( Point p1, Point p2, Point p3){ return (p2-p1)^(p3-p1);}//找凸包,返回节点数int SetConvex( Point p[], int n){ int top = 0; if( n == 0) return 0; tmp[top++] = p[0]; if( n == 1) return 1; tmp[top++] = p[1]; for( int i = 2; i < n; i++) { while( top >= 2 && sgn(xmult(tmp[top-2],tmp[top-1],p[i])) <= 0) top--; tmp[top++] = p[i]; } return top;}//三分double ternary( Point a, int l, int r){ double k = 1e30; while( l <= r) { int lm = (2*l+r)/3;//l+(r-l)*1/3 int rm = (l+2*r)/3;//l+(r-l)*2/3 double ll = (a.y-tmp[lm].y)/(a.x-tmp[lm].x); double rr = (a.y-tmp[rm].y)/(a.x-tmp[rm].x); if( sgn(ll-rr) >= 0) { k = min(k,rr); l = lm+1; } else { k = min(k,ll); r = rm-1; } } return a.y*len+(w-a.x*len)*k;}double work(){ if( sgn(len) < 0 || sgn(w) < 0)//不满足条件 return -1; sort(p,p+n); if( sgn(w-p[0].x*len) < 0)//badmood下跑的最快的runner都跑不及 return -1; int j = 1; for( int i = 0; i < n; i++) { if( sgn(p[i].y-p[j-1].y) >= 0)//goodmood下后面的速度小,不保存 continue; p[j++] = p[i];//速度大,保存下来 } n = j; if( n == 1) return p[0].y*len; for( j = 0; j < n && sgn(w-p[j].x*len) >= 0; j++)//找出临界点 ; int tot = j;//记录单个满足条件的数量 int sz = SetConvex(p+j,n-j); double ans = 1e30; for( int i = 0; i < tot; i++) { ans = min(ans,p[i].y*len); ans = min(ans,ternary(p[i],0,sz-1)); } return ans;}int main(){ int T; scanf("%d",&T); while( T--) { scanf("%d%lf%lf%lf",&n,&d,&len,&w); double s,t; double base = 0;//基础时间(也就是每个人都要跑的) for( int i = 0; i < n; i++) { scanf("%lf%lf",&s,&t); p[i].x = s; p[i].y = t; len -= d; w -= p[i].x*d; base += p[i].y*d; } double add = work(); if( sgn(add) < 0) puts("No solution"); else printf("%.2f\n",base+add); } return 0;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- <6>——ZigZag Conversion
- tensorflow进行MNIST手写数字识别-优化版
- 斐波那契数列
- 2016年总结-Java程序员
- [LintCode]7.二叉树的序列化和反序列化
- HDU
- 关于广度优先遍历(Breadth First Search)的提纲性内容
- 关于设计模式
- mybaists 一对多理解
- 如何实现hibernate的缓存机制
- Visual Studio 项目打包过程
- idea中mybatis generator自动生成代码配置 数据库是sqlserver
- Java多线程系列(一)-----基本概念
- Codeforces Round #430 (Div. 2)A,B