码迷,mamicode.com
首页 > 其他好文 > 详细

cf 700A As Fast As Possible

时间:2016-08-17 22:50:39      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

题意:有$n$个小学生需要到距离为$l$的地方去,步行的速度是$v_1$,它们租了一辆大巴,速度是$v_2$,大巴上最多容纳$k$个乘客,每个小学生最多乘车一次,初始时大巴和小学生都在起点,问至少需要多长时间所有小学生都可以到达终点。时间精确到$10^{-6}$。数据范围$1 \leq l \leq 1e9, 1 \leq v_1 < v_2 \leq 1e9, 1 \leq k \leq n$。

分析:你可能会想到用大巴把小学生送到终点再折回,如此反复,直到最后一次不折回。但是样例$2$提示我们这种贪心不是最优的,大巴不一定要把小学生送到终点,因此考虑二分时间,那么假设时间$t$内可以完成目标,可以导出每个小学生的乘车距离最少是$\frac{v_2(l-v_1t)}{v_2-v_1}$,并且大巴需要折回至少$\frac{n}{ k }- [n \mod k = 0]$次,于是根据这两个信息得出最小花费时间与$t$作比较即可完成二分。代码如下:

技术分享
  1 #include <algorithm>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <string>
  5 #include <queue>
  6 #include <map>
  7 #include <set>
  8 #include <stack>
  9 #include <ctime>
 10 #include <cmath>
 11 #include <iostream>
 12 #include <assert.h>
 13 #pragma comment(linker, "/STACK:102400000,102400000")
 14 #define max(a, b) ((a) > (b) ? (a) : (b))
 15 #define min(a, b) ((a) < (b) ? (a) : (b))
 16 #define mp std :: make_pair
 17 #define st first
 18 #define nd second
 19 #define keyn (root->ch[1]->ch[0])
 20 #define lson (u << 1)
 21 #define rson (u << 1 | 1)
 22 #define pii std :: pair<int, int>
 23 #define pll pair<ll, ll>
 24 #define pb push_back
 25 #define type(x) __typeof(x.begin())
 26 #define foreach(i, j) for(type(j)i = j.begin(); i != j.end(); i++)
 27 #define FOR(i, s, t) for(int i = (s); i <= (t); i++)
 28 #define ROF(i, t, s) for(int i = (t); i >= (s); i--)
 29 #define dbg(x) std::cout << x << std::endl
 30 #define dbg2(x, y) std::cout << x << " " << y << std::endl
 31 #define clr(x, i) memset(x, (i), sizeof(x))
 32 #define maximize(x, y) x = max((x), (y))
 33 #define minimize(x, y) x = min((x), (y))
 34 using namespace std;
 35 typedef long long ll;
 36 const int int_inf = 0x3f3f3f3f;
 37 const ll ll_inf = 0x3f3f3f3f3f3f3f3f;
 38 const int INT_INF = (int)((1ll << 31) - 1);
 39 const double double_inf = 1e30;
 40 const double eps = 1e-14;
 41 typedef unsigned long long ul;
 42 typedef unsigned int ui;
 43 inline int readint(){
 44     int x;
 45     scanf("%d", &x);
 46     return x;
 47 }
 48 inline int readstr(char *s){
 49     scanf("%s", s);
 50     return strlen(s);
 51 }
 52 
 53 class cmpt{
 54 public:
 55     bool operator () (const int &x, const int &y) const{
 56         return x > y;
 57     }
 58 };
 59 
 60 int Rand(int x, int o){
 61     //if o set, return [1, x], else return [0, x - 1]
 62     if(!x) return 0;
 63     int tem = (int)((double)rand() / RAND_MAX * x) % x;
 64     return o ? tem + 1 : tem;
 65 }
 66 ll ll_rand(ll x, int o){
 67     if(!x) return 0;
 68     ll tem = (ll)((double)rand() / RAND_MAX * x) % x;
 69     return o ? tem + 1 : tem;
 70 }
 71 
 72 void data_gen(){
 73     srand(time(0));
 74     freopen("in.txt", "w", stdout);
 75     int kases = 40000;
 76     printf("%d\n", kases);
 77     while(kases--){
 78         ll sz = 1e18;
 79         printf("%lld\n", Rand(sz, 1));
 80     }
 81 }
 82 
 83 struct cmpx{
 84     bool operator () (int x, int y) { return x > y; }
 85 };
 86 double power(double a, int p){
 87     double ans = 1.;
 88     while(p){
 89         if(p & 1) ans *= a;
 90         p >>= 1;
 91         a = a * a;
 92     }
 93     return ans;
 94 }
 95 int main(){
 96     //data_gen(); return 0;
 97     //C(); return 0;
 98     int debug = 0;
 99     if(debug) freopen("in.txt", "r", stdin);
100     //freopen("out.txt", "w", stdout);
101     int n, l, v1, v2, k;
102     while(~scanf("%d", &n)){
103         l = readint(), v1 = readint(), v2 = readint(), k = readint();
104         int lamda = n / k - (n % k == 0);
105         double L = (double)l / v2, R = (double)l / v1;
106         while(R - L > 1e-6){
107             //printf("%.10f %.10f\n", L, R);
108             //printf("err is %.10f\n", R - L);
109             double mid = (L + R) / 2;
110             //printf("mid is %.10f\n", mid);
111             double d = (double)v2 * (l - v1 * mid) / (v2 - v1);
112             double lhs = 2. * d * v1 * lamda / (v1 + v2) + d;
113             int ok = 1;
114             if(lhs >= l) ok = 0;
115             if(ok){
116                 double rhs = 2. * d * lamda / (v1 + v2);
117                 rhs += (l - lhs + d) / v2;
118                 if(rhs > mid) ok = 0;
119             }
120             if(ok) R = mid;
121             else L = mid;
122         }
123         //if(n % k) ans += d / v2;
124         printf("%.10f\n", L);
125     }
126     return 0;
127 }
code:

这里还需要注意二分的精度不能太高,否则可能由于浮点误差跳不出循环。

cf 700A As Fast As Possible

标签:

原文地址:http://www.cnblogs.com/astoninfer/p/5781981.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!