微软笔试题-highways
题目大意
一条单向的高速公路上有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的更多相关文章
- hiho一下 第一百零七周 Give My Text Back(微软笔试题)
题目1 : Give My Text Back 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 To prepare for the English exam Littl ...
- C/C++ 笔试题
/////转自http://blog.csdn.net/suxinpingtao51/article/details/8015147#userconsent# 微软亚洲技术中心的面试题!!! 1.进程 ...
- NET出现频率非常高的笔试题
又到了金三银四的跳槽季,许多朋友又开始跳槽了,这里我简单整理了一些出现频率比较高的.NET笔试题,希望对广大求职者有所帮助. 一..net基础 1. a=10,b=15,请在不使用第三方变量的情况下 ...
- 收藏所用C#技术类面试、笔试题汇总
技术类面试.笔试题汇总 注:标明*的问题属于选择性掌握的内容,能掌握更好,没掌握也没关系. 下面的参考解答只是帮助大家理解,不用背,面试题.笔试题千变万化,不要梦想着把题覆盖了,下面的题是供大家查漏补 ...
- 嵌入式Linux C笔试题积累(转)
http://blog.csdn.net/h_armony/article/details/6764811 1. 嵌入式系统中断服务子程序(ISR) 中断是嵌入式系统中重要的组成部分,这导致了很 ...
- C/C++笔试题(很多)
微软亚洲技术中心的面试题!!! .进程和线程的差别. 线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位 (2 ...
- 华为C语言笔试题集合
①华为笔试题搜集 1.static有什么用途?(请至少说明两种) 1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变. 2) 在模块内(但在函数体外),一个被声明为 ...
- 【转】C++笔试题汇总
原文:http://www.cnblogs.com/ifaithu/articles/2657663.html C#C++C多线程面试1.static有什么用途?(请至少说明两种)1)在函数体,一个被 ...
- 【转】c++笔试题
原文:http://blog.csdn.net/dongfengsun/article/details/1541926 ①链表反转 单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题. ...
随机推荐
- poj 3691 DNA repair(AC自己主动机+dp)
DNA repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5877 Accepted: 2760 Descri ...
- Introduction to SIFT (Scale-Invariant Feature Transform)
SIFT OpenCV 官方文档: https://docs.opencv.org/master/da/df5/tutorial_py_sift_intro.html https://opencv-p ...
- IOS7 隐藏状态栏 (电池栏)
电池状态栏. //方法一(代码设置): 现在ios7已经更改为透明,并且不占用屏幕高度.其中隐藏及显示的方法如下: 在uiviewcontroller的子类下,调用: if ([self re ...
- 李洪强iOS开发之苹果企业开发者账号申请流程
李洪强iOS开发之苹果企业开发者账号申请流程 一. 开发者账号类型选择 邓白氏码 DUNS number,是Data Universal Numbering System的缩写,是一个独一无二的9位数 ...
- [原]零基础学习SDL开发之移植SDL2.0到Android
在[原]SDL开发教程我们知道了如何在pc下使用SDL进行开发,在android上面是否一样可以使用呢?答案是肯定的. 下面我们进行移植SDL到Android,这里都是基于SDL最新版进行移植的,在E ...
- eclipse生成export生成jar详解
使用eclipse打jar包可能还有很多人不是很了解,今天特意测试整理一番. 打jar包有3种形式 JAR file JAR Javadoc ja ...
- Integer类型的数据比较大小
因为实体类用的是Integer包装类,所以是对象,不能直接比较大小, 一.一个Integer一个Int可以直接比较大小 二.两个Integer需要用.intValue()方法比较大小: 例如:cw.g ...
- [Kernel]理解System call系统调用
转自:http://os.51cto.com/art/200512/13510.htm 现在,您或许正在查看设备驱动程序,并感到奇怪:“函数 foo_read() 是如何被调用的?”或者可能疑惑: “ ...
- Android基础总结(十一)Fragment,动画
Fragment(重要) 用途:在一个Activity里切换界面,切换界面时只切换Fragment里面的内容 生命周期方法跟Activity一致,可以理解把其为就是一个Activity fragmen ...
- Farey Sequence(欧拉函数)
题意:给出式子F F中分子分母互质,且分子小于分母 例: F2 = {1/2} F3 = {1/3, 1/2, 2/3} F4 = {1/4, 1/3, 1/2, 2/3, 3/4} F5 = {1/ ...