Emergency Evacuation(贪心)

题目描述(中文版)

                                                                                         紧急疏散
                                                                                          时间限制:3秒
日本政府计划到2020年将入境游客人数增加到4000万,到2030年增加到6000万。不仅要增加游客的吸引力,而且要进一步发展旅游基础设施对于实现这一数字是必不可少的。
运输方面的一种可能的改进是提供极长和/或较宽的汽车,一次可搭载多名乘客。但是,太大的汽车可能需要太长时间才能在紧急情况下疏散所有乘客。请您帮助估计所需的时间。
假定汽车具有以下座椅布置。
•中央过道直通汽车,直接连接到汽车后部中央的紧急出口门。
•乘客座位数相同的行位于过道的两侧。
要求的粗略估算基于简单的逐步模型。最初,所有乘客都坐在不同的座位上,他们可以在每个步骤中进行以下任一动作。
•座位上的乘客可以朝过道移动到相邻的座位。与过道相邻的座位上的乘客可以直接向侧面移动到过道。
•过道上的乘客可以向后移动一排座位。如果乘客在紧急出口的前面,即在最后面的座位排,他/她可以下车。
要移动的座位或过道位置必须为空;或者在该步骤之前没有其他乘客在这里,或者该乘客通过在同一步骤中移至另一个位置来清空座位。当两个或两个以上的乘客满足同一位置的条件时,他们中只有一个可以移动,而其他人则保持在原来的位置等待。
图C.1的最左图描绘了样本输入1中给出的小型汽车的座椅布置。该汽车有五排座椅,在过道两侧各有两个座椅,共二十个。还显示了船上七名乘客的初始位置。
图C.1的另外两个图显示了第一步和第二步之后乘客的可能位置。乘客的移动由粗箭头指示。请注意,前排座位中的两名乘客必须在第一步中等待空缺,而第二排中的一名乘客必须在下一步中等待。
您的任务是编写一个程序,在给定座位安排和乘客初始位置的情况下,为所有乘客下车提供尽可能少的步骤。

错误的思路分析

  我上来看到这道题的第一印象就是模拟人们下车的过程,当时没有考虑时间效率,就调出来了一个极其难看的代码,跑的还贼慢。大家感兴趣的可以看看我的笨蛋思路。

1. 在考虑下车时,由于开始时过道两边可能都有人坐,我们就要考虑是左边先下还是右边先进过道的问题

我们便可以假设有如图的一种情况,我们设他们相邻过道上的位置距离出口d,则三个点无论以什么样的顺序出,最终耗时都为(d+1)+(d+1)+(d+2)即3d+4个单位时间,所以相邻过道两边的先后进入过道的顺序与最终答案无关。

2. 若出现如下图的情况,红色的人应该先插入过道还是待一列人走完后从末尾跟着走(有颜色代表有人)

我们可以假设红色在前面,则该五个人出去所需的总时间为7个单位时间,而让红色跟在后面,则需要8个单位时间,故如果在过道边坐着的人如果可以进入过道的话就让优先进入过道。

则我们最终模拟的顺序为先让能进入过道的人先进过道,再让中间的还没动过的人向下走,最后往中间移得动的人向中间动,这是一次移动,最后计数即可。

弄上代码

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 const int N=500;
 5 const int maxn=N*N;
 6 struct People{  //People保存每个人的位置(x,y),是否下车(chu)
 7     int x,y;    // 本轮是否移动(ok)
 8     bool chu,ok;
 9 }pe[N];
10 int a[N][N];    //存储车的平面图.
11 int id[N][N];   //存储每个位置的编号
12 int r,s,p,mid;
13 int ans=0;
14 int main(){
15     scanf("%d%d%d",&r,&s,&p);
16     int mid=s+1;
17     for(int i=1;i<=p;++i){
18         int x,y;
19         scanf("%d%d",&x,&y);
20         if(y>=mid) y++;
21         a[x][y]=1;
22         id[x][y]=i;
23         pe[i].x=x;pe[i].y=y;
24     }
25     int cnt=p;
26     while(cnt){
27         for(int i=1;i<=p;++i)   //每轮更新
28             pe[i].ok=0;
29         for(int i=1;i<=p;++i){   //可以进过道的进过道
30             if(pe[i].y==s&&!a[pe[i].x][mid]){
31                 int x=pe[i].x,y=pe[i].y;
32                 a[x][y]=0;a[x][y+1]=1;
33                 pe[i].y++;id[x][y+1]=id[x][y];id[x][y]=0;
34                 pe[i].ok=1;
35             }
36             if(pe[i].y==s+2&&!a[pe[i].x][mid]){
37                 int x=pe[i].x,y=pe[i].y;
38                 a[x][y]=0;a[x][y-1]=1;
39                 pe[i].y--;id[x][y-1]=id[x][y];id[x][y]=0;
40                 pe[i].ok=1;
41             }
42         }
43         for(int i=r;i>=1;--i){   //过道可以往下走的往下走.
44             int t=id[i][mid];
45             if(!t||pe[t].chu) continue;
46             if(pe[t].ok) continue;
47             if(i==r){
48                 pe[t].chu=true;a[i][mid]=0;
49                 cnt--;
50             }
51             else if(a[i+1][mid]) continue;
52             a[i+1][mid]=1;a[i][mid]=0;
53             pe[t].x=i+1;pe[t].ok=1;
54             id[i+1][mid]=id[i][mid];id[i][mid]=0;
55         }
56         for(int i=1;i<=p;++i){  //两边可以向中间靠的向中间靠.
57             int x=pe[i].x,y=pe[i].y;
58             if(pe[i].chu) continue;
59             if(y==mid) continue;
60             if(y<mid){
61                 if(a[x][y+1]) continue;
62                 a[x][y+1]=1;a[x][y]=0;id[x][y+1]=id[x][y];id[x][y]=0;
63                 pe[i].ok=true;pe[i].y=y+1;
64                 while(a[x][y-1]&&!pe[id[x][y-1]].ok){
65                     if(y>=mid||y<1) break;
66                     a[x][y-1]=0;a[x][y]=1;id[x][y]=id[x][y-1];id[x][y-1]=0;
67                     pe[id[x][y]].ok=true;pe[id[x][y]].y++;
68                     y--;
69                 }
70             }
71             if(y>mid){
72                 if(a[x][y-1]) continue;
73                 a[x][y-1]=1;a[x][y]=0;id[x][y-1]=id[x][y];id[x][y]=0;
74                 pe[i].ok=true;pe[i].y--;
75                 while(a[x][y+1]&&!pe[id[x][y+1]].ok){
76                     if(y<=mid||y>2*s+1) break;
77                     a[x][y+1]=0;a[x][y]=1;id[x][y]=id[x][y+1];id[x][y+1]=0;
78                     pe[id[x][y]].ok=true;pe[id[x][y]].y--;
79                     y++;
80                 }
81             }
82         }
83         ans++;  //统计次数
84     }
85     printf("%d\n",ans);
86     return 0;
87 }

如果你这样写了,恭喜你,由于超时你一个点都过不了。

下面才是正确思路及写法

我们可以逆序考虑,既然求下车的最大时间,我们可以转化为每个人都在车下,先后上车到他的座位,求出上车最慢的等待时间即可。每个人的时间开销为上车时间+等待时间,则根据贪心的思想,我们可以对每个人的上车时间进行排序,时间花销大的先上车,最后将每个人的上车时间和等待时间之和取最大值即可。(每个人的时间开销即从座位到出口的距离)

附上代码

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=500*500;
 6 struct People{ //保存每个人的位置,及距出口的距离.
 7     int r,c;
 8     int d;
 9 }pe[N];
10 bool cmp(People a,People b){
11     return a.d>b.d;
12 }
13 int main(){
14     int r,s,p;
15     scanf("%d%d%d",&r,&s,&p);
16     for(int i=1;i<=p;++i){
17         scanf("%d%d",&pe[i].r,&pe[i].c);
18         if(pe[i].c>s)   //计算距离,横向加竖向.
19             pe[i].d=(pe[i].c-s)+(r-pe[i].r+1);
20         else
21             pe[i].d=(s-pe[i].c+1)+(r-pe[i].r+1);
22     }
23     sort(pe+1,pe+1+p,cmp);
24     int k=1;  //k由于计算每个人的等待时间
25     int max_time=pe[1].d;
26     for(int i=2;i<=p;++i){
27         if(pe[i].d+k>max_time)
28             max_time=pe[i].d+k;  //计算最大时间开销
29         k++;
30     }
31     printf("%d\n",max_time);
32     return 0;
33 }

正确写法及思路来自https://blog.csdn.net/qq_40534166/article/details/88894175?depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1&utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1

原文地址:https://www.cnblogs.com/li-jia-hao/p/12677043.html

时间: 2024-08-01 18:02:48

Emergency Evacuation(贪心)的相关文章

ICPC 2018 亚洲横滨赛 C Emergency Evacuation(暴力,贪心)

ICPC 2018 亚洲横滨赛 C Emergency Evacuation 题目大意 你一个车厢和一些人,这些人都坐在座位上,求这些人全部出去的时间最小值 Solution 题目咋说就咋做 直接模拟 我们考虑每个人的路线,如果这两个人在没有阻挡的情况下,到达终点的时间是一样的话,那么必定会在某一点相遇. 此时就需要有一个人要等一个时刻,如果有第三个人的话,这第三个就要等两个时刻,那么我们直接算出每个人到终点的时间,排序后依次后延即可. #include <cstdio> #include &

Emergency Evacuation题解

题目 The Japanese government plans to increase the number of inbound tourists to forty million in the year 2020, and sixty million in 2030. Not only increasing touristic appeal but also developing tourism infrastructure further is indispensable to acco

2018-2019, ICPC, Asia Yokohama Regional Contest 2018 (Gym - 102082)

2018-2019, ICPC, Asia Yokohama Regional Contest 2018 A - Digits Are Not Just Characters 签到. B - Arithmetic Progressions 题意:从给定的集合中选出最多的数构成等差数列. 题解:数字排序后,设\(dp[i][j]\)表示等差数列最后一个数字为\(a[i]\),倒数第二个数字为\(a[j]\)的最大个数.然后对于每一位枚举 \(i\),\(lower\_bound()\)找有无合法的

2019 ICM Problem D: Time to leave the Louvre

2019 ICMProblem D: Time to leave the LouvreThe increasing number of terror attacks in France[1]requires a review of the emergencyevacuation plans at many popular destinations. Your ICM team is helping to design evacuationplans at the Louvre in Paris,

解题报告 之 POJ3057 Evacuation

解题报告 之 POJ3057 Evacuation Description Fires can be disastrous, especially when a fire breaks out in a room that is completely filled with people. Rooms usually have a couple of exits and emergency exits, but with everyone rushing out at the same time

Intelligence System (hdu 3072 强联通缩点+贪心)

Intelligence System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1650    Accepted Submission(s): 722 Problem Description After a day, ALPCs finally complete their ultimate intelligence syste

【uva 1615】Highway(算法效率--贪心 区间选点问题)

题意:给定平面上N个点和一个值D,要求在x轴上选出尽量少的点,使得对于给定的每个店,都有一个选出的点离它的欧几里德距离不超过D. 解法:先把问题转换成模型,把对平面的点满足条件的点在x轴的直线上可得到一个个区间,这样就是选最小的点覆盖所有的区间的问题了.我之前的一篇博文有较详细的解释:关于贪心算法的经典问题(算法效率 or 动态规划).代码实现我先空着.挖坑~

【贪心+Treap】BZOJ1691-[Usaco2007 Dec]挑剔的美食家

[题目大意] 有n头奶牛m种牧草,每种牧草有它的价格和鲜嫩度.每头奶牛要求它的牧草的鲜嫩度要不低于一个值,价格也不低于一个值.每种牧草只会被一头牛选择.问最少要多少钱? [思路] 显然的贪心,把奶牛和牧草都按照鲜嫩度由大到小排序,对于每奶牛把鲜嫩度大于它的都扔进treap,然后找出后继. 不过注意后继的概念是大于它且最小的,然而我们这里是可以等于的,所以应该是找cow[i].fresh-1的后继,注意一下…… 1 #include<iostream> 2 #include<cstdio&

POJ1017 Packets(贪心算法训练)

Time Limit: 1000MS          Memory Limit: 10000K          Total Submissions: 51306          Accepted: 17391 Description A factory produces products packed in square packets of the same height h and of the sizes 1*1, 2*2, 3*3, 4*4, 5*5, 6*6. These pro