zoukankan      html  css  js  c++  java
  • Problem C Emergency Evacuation 一道思维题

    题目描述

     

     

    输入

      

    输出

     

     样例

    样例输入

    5 2 7
    1 1
    1 2
    1 3
    2 3
    2 4
    4 4
    5 2
    样例输入一
    500 500 16
    1 1
    1 2
    1 999
    1 1000
    2 1
    2 2
    2 999
    2 1000
    3 1
    3 2
    3 999
    3 1000
    499 500
    499 501
    499 999
    499 1000
    样例输入二

    样例输出

    样例输出一

    9

    样例输出二

    1008

    一句话题意:给你一个车厢和一些人,这些人都坐在座位上,求这些人全部出去的时间最小值。

    分析

    我们先拿最简单的情况来说:车厢中只有一个人,比如下面这幅图

     那么很显然,他到达出口所需要的花费步数为5+1=6

    是不是太简单了,那我们再加一个人

    那么新加的这个人到出口所需要的步数为2+2=4

    因为6大于4,所以在第一个人到达距离出口的步数为2的地方时,第二个人已经从出口离开车厢,不会对结果造成影响

    最终答案仍为6

    那么我们再加一个人

     第三个人到达出口所需要的时间为1+1=2

    因为2、4、6都不相等,所以此时最终答案仍然为6

    这时,我们要加一个最为关键的人——四号

     我们会发现4号到达出口的时间和1号一样都为6

    这时,问题就来了,1号和4号显然不能同时走出车厢,而他们走出车厢的最小步数又都为6

    所以,1号和4号必定有一个人需要停留一步,在下一步时再排到另一个人的后面

    这时,因为有了停留的这一步,最大步数就变成了6+1=7

    我们再加一个人,把最后一种情况考虑到

     5号到达门口需要的最少步数为2+5=7,那么他能不能在第七步时走出车厢呢

    答案是不能的,因为前面的1号和4号都需要走六步才能到达出口

    1号和4号中必定有一个人会花费7步,这时会与5号的7步相冲突

    所以5号又要推迟一步,变成8步

    同样的我们再加一个人

     6号需要的步数也为7,所以5号又要推迟一步,变为9步

    最后我们再把剩余的一个人加上

    他的步数为5步,所以不会对结果产生影响

    所以样例一的最终答案为9步

    代码

    知道了思路,下一步就是代码实现了

    我们要先处理出每一个人到达出口的最小步数,然后排一下序

    最后我们由大到小遍历,如果遇到相同的就把步数往后推一个

    需要注意的是,数组要开500*500*2,不要开小了

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 using namespace std;
     6 const int maxn=5000011;//数组不要开小了
     7 int r,s,p;
     8 int jl[maxn];
     9 int solve(int bb){
    10     if(bb<=s) return s-bb+1;
    11     else return bb-s;
    12 }
    13 int main(){
    14     scanf("%d%d%d",&r,&s,&p);
    15     for(int i=1;i<=p;i++){
    16         int aa,bb;
    17         scanf("%d%d",&aa,&bb);
    18         jl[i]=r-aa+1+solve(bb);//求出每个节点到出口的最小步数
    19     }
    20     sort(jl+1,jl+1+p);//排序
    21     int ans=-1,cnt=0;
    22     for(int i=1;i<=p;i++){
    23         if(jl[i]==cnt || ans>=jl[i]) ans++;
    24         //如果出现相同的或者是当前的最大步数大于等于该节点的步数,步数往后推移一步
    25         //这里的当前的最大步数大于等于该节点的步数说明之前一定遍历到了比jl[i]更小的节点
    26         //而且该节点被遍历了两次及以上,这时我们也需要把ans++
    27         else ans=max(ans,jl[i]);//不相同取较大值
    28         cnt=jl[i];//记录上一个元素
    29     }
    30     printf("%d
    ",ans);
    31     return 0;
    32 }
    View Code
  • 相关阅读:
    使用带Arduino IDE & WIZ820io的ATmega1284P
    初学者使用IntellJ IDEA建立Struts2项目
    树状数组
    hdu 4605-Magic Ball Game(树状数组)
    hdu1547之BFS
    面向服务的体系结构(SOA)——(3)关于BPM
    电信运营商移动互联网发展分析
    共享IP云主机(VPS)玩转wdcp
    从 Windows 到 Android: 威胁的持续迁移
    java 存储oracle的clob字段
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/12674742.html
Copyright © 2011-2022 走看看