题目大意

一条单向的高速公路上有N辆车,在0时刻,每辆车分别在起点A[0],A[1]....处开始从北向南出发,每辆车有个终点B[0],B[1]....且每辆车有个限制速度 V[0],V[1]... 路上不能超车,即车X可能因为速度较慢,会挡住后面的车Y,但车X到达它的终点之后就消失了,不会再阻挡后面的车。 
    求出每辆车到达各自终点的最短时间。题目见 http://hihocoder.com/contest/hiho65/problem/1

题目分析

  此题采用模拟的方法来解决,对于每辆车都有一个终点,题目也需要我们求出每辆车到达它的终点的最短时间。但是在车行进的过程中,可能会由于其他车的阻挡而无法始终以最大速度行进,这需要我们知道每辆车在什么时间段可以最大速度行进,什么时间段只能紧贴着前车行进。这样来解决就比较麻烦,可以转换一下: 
(1)由于车道为单向,因此后车不会对前面的车产生影响,而后车受到前面车的影响。因此将车按照起始位置进行排序,然后按照从前向后的顺序确定每辆车到达其终点的顺序。 
(2)因为考虑车A时,车A前面的车会对车A造成影响,而且影响会在前面的某车B到达车B的终点之后结束。因此,所有车的终点,都应该被视为一个重要因素,所以,保存车A前面的所有车到达车A前面的那些所有终点的时间。 
(3)再考虑一下,发现不需要保存A前面所有车B1,B2...到达A前面所有终点Fi, Fi+1....的时间。我们先对A前面的终点排序,从A出发到达那些终点肯定是按照从近到远的顺序到达。我们按照模拟的方法,从近到远分阶段考察A到达Fi,Fi+1,Fi+2..的时间,考虑A从Fj到Fj+1的时间,因为考虑A之前,已经获得了A前面的那些车到达Fj+1的时间,此时,我们需要知道的是A前面的那些车到达Fj的最大的时间M,若A以全速从Fj到达Fj+1的时间(记录的是从A的起点到达Fj+1的时间)大于M,则说明A的速度不够,否则说明A的前面的车阻挡A。两种情况下,更新M,以及A到达Fj+1的时间。当A到达其终点A.end的时候,就记录A到达的时间,该时间就是A到达的最短时间。

所以,只需要记录每个终点有车到达的最大的时间即可。

实现(c++)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define MAX_CAR_NUM 1005 /*
此题采用模拟的方法来解决,对于每辆车都有一个终点,题目也需要我们求出每辆车到达它
的终点的最短时间。但是在车行进的过程中,可能会由于其他车的阻挡而无法始终以最大速度行进,
这需要我们知道每辆车在什么时间段可以最大速度行进,什么时间段只能紧贴着前车行进。这样来解决就
比较麻烦,可以转换一下:
(1)由于车道为单向,因此后车不会对前面的车产生影响,而后车受到前面车的影响。因此将车按照起始位置进行
排序,然后按照从前向后的顺序确定每辆车到达其终点的顺序。
(2)因为考虑车A时,车A前面的车会对车A造成影响,而且影响会在前面的某车B到达车B的终点之后结束。因此,
所有车的终点,都应该被视为一个重要因素,所以,保存车A前面的所有车到达车A前面的那些所有终点的时间。
(3)再考虑一下,发现不需要保存A前面所有车B1,B2...到达A前面所有终点Fi, Fi+1....的时间。我们先对A前面的终点排序,
从A出发到达那些终点肯定是按照从近到远的顺序到达。我们按照模拟的方法,从近到远分阶段考察A到达Fi, Fi+1,Fi+2..的时间,
考虑A从Fj到Fj+1的时间,因为考虑A之前,已经获得了A前面的那些车到达Fj+1的时间,此时,我们需要知道的是A前面的那些车
到达Fj的最大的时间M,若A以全速从Fj到达Fj+1的时间(记录的是从A的起点到达Fj+1的时间)大于M,则说明A的速度不够,否则说明
A的前面的车阻挡A。两种情况下,更新 M,以及A到达Fj+1的时间。当A到达其终点A.end的时候,就记录A到达的时间,该时间
就是A到达的最短时间。 所以,只需要记录每个终点有车到达的最大的时间即可。
*/
int gEndPoint[MAX_CAR_NUM]; //保存各个终点的位置
double gMaxEndTime[MAX_CAR_NUM];
int gCarIndex[MAX_CAR_NUM];
struct Car{
int start_point;
int end_point;
int end_index;
double v_limit;
double arrive_time;
};
Car gCars[MAX_CAR_NUM]; //用于对车的索引按照车的起点位置排序,
bool Compare1(int index1, int index2){
return gCars[index1].start_point < gCars[index2].start_point;
} //根据车A的起点,找到车A需要经过的那些终点的起始序号(终点经过排序)
int GetEndIndex(int start, int n){
int beg = 0, end = n;
while (beg < end){
int mid = (beg + end) / 2;
if (gEndPoint[mid] == start)
return mid;
else if (gEndPoint[mid] > start)
end = mid;
else
beg = mid + 1;
}
return beg;
} int main(){
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++){
scanf("%d %d %lf", &gCars[i].start_point, &gCars[i].end_point, &gCars[i].v_limit);
gEndPoint[i] = gCars[i].end_point;
gCarIndex[i] = i;
}
memset(gMaxEndTime, 0, sizeof(gMaxEndTime)); //对车的索引排序 gCarIndex[0]表示起点最小的车在gCar中的位置,gCarIndex[1]表示起点第二小的车在gCar中的位置
sort(gCarIndex, gCarIndex + n, Compare1); //对终点进行排序
sort(gEndPoint, gEndPoint + n); for (int i = 0; i < n; i++){
gCars[i].end_index = GetEndIndex(gCars[i].end_point, n); //二分法确定车的终点序号,用于当车到达终点时记录
} //从前向后考虑
for (int i = n - 1; i >= 0; i--){
int start_index = GetEndIndex(gCars[gCarIndex[i]].start_point, n);
double time = 0, point = gCars[gCarIndex[i]].start_point, v_limit = gCars[gCarIndex[i]].v_limit;
//考察车A的路程经过的那些终点即可
for (int index = start_index; index <= gCars[gCarIndex[i]].end_index; index++){
if (time + (gEndPoint[index] - point) / v_limit > gMaxEndTime[index]){ //判断是否前车阻挡
time += (gEndPoint[index] - point) / v_limit;
gMaxEndTime[index] = time;
}
else{
time = gMaxEndTime[index];
}
if (gCars[gCarIndex[i]].end_index == index){//到达终点进行更新
gCars[gCarIndex[i]].arrive_time = gMaxEndTime[index];
} point = gEndPoint[index];
}
}
for (int i = 0; i < n; i++){
printf("%.2lf\n", gCars[i].arrive_time);
}
return 0;
}

微软笔试题-highways的更多相关文章

  1. hiho一下 第一百零七周 Give My Text Back(微软笔试题)

    题目1 : Give My Text Back 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 To prepare for the English exam Littl ...

  2. C/C++ 笔试题

    /////转自http://blog.csdn.net/suxinpingtao51/article/details/8015147#userconsent# 微软亚洲技术中心的面试题!!! 1.进程 ...

  3. NET出现频率非常高的笔试题

    又到了金三银四的跳槽季,许多朋友又开始跳槽了,这里我简单整理了一些出现频率比较高的.NET笔试题,希望对广大求职者有所帮助. 一..net基础 1.  a=10,b=15,请在不使用第三方变量的情况下 ...

  4. 收藏所用C#技术类面试、笔试题汇总

    技术类面试.笔试题汇总 注:标明*的问题属于选择性掌握的内容,能掌握更好,没掌握也没关系. 下面的参考解答只是帮助大家理解,不用背,面试题.笔试题千变万化,不要梦想着把题覆盖了,下面的题是供大家查漏补 ...

  5. 嵌入式Linux C笔试题积累(转)

    http://blog.csdn.net/h_armony/article/details/6764811 1.   嵌入式系统中断服务子程序(ISR) 中断是嵌入式系统中重要的组成部分,这导致了很 ...

  6. C/C++笔试题(很多)

    微软亚洲技术中心的面试题!!! .进程和线程的差别. 线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位 (2 ...

  7. 华为C语言笔试题集合

    ①华为笔试题搜集 1.static有什么用途?(请至少说明两种)     1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变.     2) 在模块内(但在函数体外),一个被声明为 ...

  8. 【转】C++笔试题汇总

    原文:http://www.cnblogs.com/ifaithu/articles/2657663.html C#C++C多线程面试1.static有什么用途?(请至少说明两种)1)在函数体,一个被 ...

  9. 【转】c++笔试题

    原文:http://blog.csdn.net/dongfengsun/article/details/1541926 ①链表反转 单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题. ...

随机推荐

  1. NS3网络仿真(6): 总线型网络

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载.但请保留作者信息 在NS3提供的第一个演示样例first.py中,模拟了一个点对点的网络,接下来的一个演示样例代码模 ...

  2. sql中一列拆成两列

    declare @table table (name nvarchar(4))insert into @tableselect '张三' union allselect '李四' union alls ...

  3. linux 下安装 jdk tomcat 并配置

    linux下安装TOMCAT与JDK 第1步:新建boss用户,username:boss,password:boss 第2步:将安装用户路径设置成/app/boss [root@localhost] ...

  4. 点滴积累【other】---HTTP 错误 404.13 - Not Found,请求筛选模块被配置为拒绝超过请求内容长度的请求(转载)

    此文参考来源:http://blog.csdn.net/tiantian1980/article/details/6577499 问题:HTTP 错误 404.13 - Not Found,请求筛选模 ...

  5. 手把手教做Excel直方图

    手把手教做Excel直方图 2017-10-05  作者:ExcelHome  阅读:71968次   直方图是用于展示数据的分组分布状态的一种图形,用矩形的宽度和高度表示频数分布,通过直方图,用户可 ...

  6. java中,scala中代码检测当前环境的版本

    //来自spark源码// sparkContext初始化的时候写着  private def warnDeprecatedVersions(): Unit = { val javaVersion = ...

  7. 使用tcpdump观察IPV4头部结构

    sudo tcpdump -nt -i lo  #抓取本地回路上的数据包 先运行上面的命令,然后再另一个终端运行下图所示的命令: [root@linux 5]# sudo tcpdump -nt -i ...

  8. Spring.Net框架一:Spring.Net简介

    一.Spring.Net简介 Spring.NET为建立企业级应用提供了一套轻量级的解决方案.通过Spring.NET,我们可以用统一且透明的方式来配置应用程序.Spring.NET的重点是为中间层提 ...

  9. HeadFirst 设计模式 04 工厂模式

    除了 new 操作符之外, 还有更多创造对象的方法. 工厂处理创建对象的细节. 这么做的目的是为了抽象, 例如把创建比萨的代码包装进一个类, 当以后实现改变时, 只需修改这个类即可. 利用静态方法定义 ...

  10. Linux 复制、移动覆盖文件不提示

    # vi ~/.bashrc   如果你看到如下内容,以下命令都会用别名执行了,就是说自动加了 -i 参数 alias rm='rm -i'alias cp='cp -i'alias mv='mv - ...