Vacation

题目传送门

update(O(n))

看了那个O(n)的方法,感觉自己想的那个O(nlogn)的好傻,awsl。

0车最终通过停车线的时候,状态一定是某个车堵住后面的所有车(这个车也可以是0车)。所以我们要找的就是那个把后面所有都堵住的最前面的车x,x车没有被别的车堵住,从头到尾都按照初始速度行驶,当0车到停车线时,这x车走过的距离d = s_x + 0到x车的车身长度和,时间为d/v_x。

我们假设所有的车都是车x,求出时间,其中最大时间即为答案。因为如正确的时间t = (车i行驶的总路程/车i的平均速度).如果一辆车的速度改变过,只会变小,而用原来的速度算会使答案偏小,而如果这辆车在车x的前面,与x有一段距离,那参与运算的d就偏小了,算出的时间就会偏小。

以下为代码

  1. #include <bits/stdc++.h>
  2. #define INF 0x3f3f3f3f
  3. using namespace std;
  4. typedef long long ll;
  5. const int N = 100005;
  6. double l[N], s[N], v[N];
  7. double len[N];
  8. int main()
  9. {
  10. int n;
  11. while(scanf("%d", &n) != EOF){
  12. for(int i = 0; i <= n; i ++)
  13. scanf("%lf", &l[i]);
  14. for(int i = 0; i <= n; i ++)
  15. scanf("%lf", &s[i]);
  16. for(int i = 0; i <= n; i ++)
  17. scanf("%lf", &v[i]);
  18. len[0] = 0;
  19. for(int i = 1; i <= n; i ++)
  20. len[i] = len[i - 1] + l[i];
  21. double ans = 0.0;
  22. for(int i = 0; i <= n; i ++)
  23. ans = max(ans, (s[i] + len[i]) / v[i]);
  24. printf("%.10f\n", ans);
  25. }
  26. return 0;
  27. }

解题思路(O(nlog)n)

一开始的时候所有车都是是按照自己原来的速度行驶,直到有一辆车x追上前面的那辆车y,此时的变化只有,1.x的速度变为y的速度2.x后面的车追上x的时间变短。所以我们只要利用优先队列,每一次都找到会在最短的时间内追上前面那辆车的x,不断更新这个过程就好了。

以及实现中的一些细节,1.对于已经追上和被追上的两辆车,我们可以看成一辆火车,每辆车就是一节车厢,其速度就是最前面那节车厢的速度,当一辆火车追上另一辆的时候,新的火车头就是前面被追上车厢的火车头,新的火车尾就是后面火车的火车尾,所以我们记录每节作为火车头的车厢对应的火车尾,和每节火车尾对应的火车头。2.优先队列中的时间指是第几秒会追上前面的车。由于前面的车会变速,所以要记录上一次变速的时间,以及上一次变速前已经走了多少或还剩下多少距离。3.只有后面的车可以追上前面的车时才进队。

还有就是,不要直接memset,数据组数很多,会超时。

代码如下

  1. #include <bits/stdc++.h>
  2. #define INF 0x3f3f3f3f
  3. using namespace std;
  4. typedef long long ll;
  5. const int N = 100005;
  6. double len[N], s[N], v[N];
  7. int l[N], r[N];
  8. struct T{
  9. double t;
  10. int x;
  11. T(int x, double t): x(x), t(t){}
  12. bool operator<(const T& a)const{
  13. return t > a.t;
  14. }
  15. };
  16. bool vis[N];
  17. double t[N], dis[N];
  18. int main()
  19. {
  20. int n;
  21. while(scanf("%d", &n) != EOF){
  22. for(int i = 0; i <= n; i ++)
  23. scanf("%lf", &len[i]); //车长
  24. for(int i = 0; i <= n; i ++)
  25. scanf("%lf", &s[i]);
  26. for(int i = 0; i <= n; i ++)
  27. scanf("%lf", &v[i]);
  28. for(int i = 0; i <= n; i ++)
  29. l[i] = r[i] = i;
  30. priority_queue<T> pq;
  31. for(int i = 0; i < n; i ++){
  32. t[i] = 0.0;
  33. vis[i] = false;
  34. dis[i] = s[i] - s[i + 1] - len[i + 1];
  35. if(v[i] > v[i + 1])
  36. pq.push(T(i, dis[i] / (v[i] - v[i + 1])));
  37. }
  38. double d = 0.0; //0号车已走的路程
  39. double last = 0.0;
  40. while(!pq.empty()){
  41. T top = pq.top();
  42. pq.pop();
  43. if(vis[top.x])
  44. continue;
  45. vis[top.x] = true;
  46. double time = top.t;
  47. int x = top.x;
  48. if(d + v[r[0]] * (time - last) >= s[0])
  49. break;
  50. d += v[r[0]] * (time - last);
  51. r[l[x]] = r[x + 1];
  52. l[r[x + 1]] = l[x];
  53. if(l[x] != 0){
  54. dis[l[x] - 1] -= (time - t[l[x] - 1]) * (v[l[x] - 1] - v[x]);
  55. t[l[x] - 1] = time;
  56. if(v[l[x] - 1] > v[r[x + 1]])
  57. pq.push(T(l[x] - 1, time + dis[l[x] - 1] / (v[l[x] - 1] - v[r[x + 1]])));
  58. }
  59. last = time;
  60. }
  61. printf("%.10f\n", last + (s[0] - d) / v[r[0]]);
  62. }
  63. return 0;
  64. }

2019杭电多校第一场hdu6581 Vacation的更多相关文章

  1. [2019杭电多校第一场][hdu6582]Path(最短路&&最小割)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6582 题意:删掉边使得1到n的最短路改变,删掉边的代价为该边的边权.求最小代价. 比赛时一片浆糊,赛后 ...

  2. [2019杭电多校第一场][hdu6583]Typewriter(后缀自动机&&dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6583 大致题意是说可以花费p在字符串后添加一个任意字符,或者花费q在字符串后添加一个当前字符串的子串. ...

  3. [2019杭电多校第一场][hdu6579]Operation(线性基)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6579 题目大意是两个操作,1个是求[l,r]区间子序列的最大异或和,另一个是在最后面添加一个数. 如果 ...

  4. [2019杭电多校第一场][hdu6578]Blank(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6578 计数问题想到dp不过分吧... dp[i][j][k][w]为第1-i位置中4个数最后一次出现的 ...

  5. 2019杭电多校第一场hdu6579 Operation(线性基)

    Operation 题目传送门 解题思路 把右边的数尽量往高位放,构造线性基的时候同时记录其在原序列中的位置,在可以插入的时候如果那个位置上存在的数字的位置比新放入的要小,就把旧的往后挤.用这种发现构 ...

  6. 2018 Multi-University Training Contest 1 杭电多校第一场

    抱着可能杭电的多校1比牛客的多校1更恐怖的想法 看到三道签到题 幸福的都快哭出来了好吗 1001  Maximum Multiple(hdoj 6298) 链接:http://acm.hdu.edu. ...

  7. 2019年杭电多校第一场 1004题Vacation(HDU6581+数学)

    题目链接 传送门 题意 有\(n+1\)辆车要过红绿灯,告诉你车的长度.与红绿灯的起点(题目假设红绿灯始终为绿).车的最大速度,问你第\(0\)辆车(距离最远)车头到达红绿灯起点的时间是多少(每辆车最 ...

  8. 2019年杭电多校第一场 1009题String(HDU6586+模拟+单调栈)

    题目链接 传送门 题意 给你一个字符串,要你构造一个长为\(k\)的子串使得每个字母出现的次数在\([L_i,R_i](0\leq i\leq26)\)间且字典序最小. 思路 做这种题目就是要保持思路 ...

  9. 2019年杭电多校第一场 1002题Operation(HDU6579+线性基)

    题目链接 传送门 题意 初始时有\(n\)个数,现在有\(q\)次操作: 查询\([l,r]\)内选择一些数使得异或和最大: 在末尾加入一个数. 题目强制在线. 思路 对于\(i\)我们记录\([1, ...

随机推荐

  1. 验证码生成器(在TImage.Canvas上写字,很好看)

    生成验证码的方式有很多种,如下则是比较简单的实现,且运用了正余弦曲线来扭曲验证码字符. unit AuthenticodeGenerate; interface uses SysUtils, Wind ...

  2. 发现 TSplitter 在嵌套时不好用, 索性写了个替代品(处理MouseDown,MouseMove,MouseUp,然后设定控件的Left值就可以了)

    代替 TSplitter 的 TDirPanel 类: unit DirPanel; interface uses   Classes, Controls, Forms, ExtCtrls; type ...

  3. spring boot单元测试之RestTemplate(一)

    写代码重要,写好的代码准确无误,且符合预期那更是必不可少. spring boot内嵌了专门的单元测试模块——RestTemplate,保证了程序员可以对自己的代码进行及时的测试. 闲言少叙,直接上代 ...

  4. sublimetext插件安装

    sublimetext 一.下载地址: https://www.sublimetext.com/ 二.安装Package Control 方式一: Ctrl + Shift + P , 输入insta ...

  5. scala class中孤立代码块揭秘

    在 scala class中,经常会有很多的代码块需要执行,它们不在任何方法中,只是孤立的代码块. 案例: class Tester(val name:String, num:Integer) { p ...

  6. Adboe Flash远程代码执行_CVE-2018-4878漏洞复现

    Adboe Flash远程代码执行_CVE-2018-4878漏洞复现 一.漏洞描述 该漏洞可针对windows用户发起定向攻击.攻击者可以诱导用户打开包含恶意Flash代码文件的Microsoft ...

  7. 【设计模式】行为型11解释器模式(Interpreter Pattern)

      解释器模式(Interpreter Pattern) 解释器模式应用场景比较小,也没有固定的DEMO,中心思想就是自定义解释器用来解释固定的对象. 定义:给定一个语言,定义它的文法表示,并定义一个 ...

  8. linux下svn安装

    1.环境centos6.4 2.安装svnyum -y install subversion 3.配置 建立版本库目录mkdir /www/svndata svnserve -d -r /www/sv ...

  9. yii中常用路径

    //YII framework路径Yii::getFrameworkPath(); //protected/runtimeYii::app()->getRuntimePath(); //在vie ...

  10. HTTP协议之应用

    通过对http协议的理解.我们可以根据这些特性来进行一些应用. 1.我们可以根据http请求的头信息refer信息,我们可以来做网站的防盗链.refer记录访问到目标网站的上次访问路径.这样我们可以来 ...