最短时间到达指定路口
【来源】网传的2018阿里秋招笔试题
【问题描述】
城市有 N 个路口,每个路口有自己编号,从0 ~ N-1, 每个路口有自己的交通控制信号,比如 0,3 表示 0 号路口的交通信号每隔 3 个时刻变化一次,即0,1,2时刻可以过,而3,4,5时刻不能过,而6,7,8时刻又可以过,以次类推,所有路口的允许时刻都从 0 时刻开始。城市有 M 条道路把这 N 个路口连接起来,0,1,4 表示该道路联通路口 0 和路口 1,道路通过距离需要 4 个时刻。现指定出发路口和终点路口,由 0 时刻出发,最快能在什么时间到达?
【输入】
N路口的个数 N个路口,第一列是路口id,第二列是该路口通行周期 M 路的条数 M条路,第一列路一端的路口,第二列路另一端的路口,第三列通行所需要的时间 S起点,T目标点
【输出】
最短时间
【输入范例】
9
0,3
1,5
2,7
3,3
4,5
5,7
6,9
7,3
8,5
14
0,1,4
0,7,8
1,2,8
1,7,11
2,3,7
2,5,4
2,8,2
3,4,9
3,5,14
4,5,10
5,6,2
6,8,6
6,7,1
7,8,7
0,4
【输出范例】
28
【算法思路】
这个题目与滴滴笔试题:青蛙走迷宫,最快走到出口是完全同一类型的题目,下面用递归分治法解。
当然可能有好的其他算法,下次再尝试。
【程序】
1 #include <iostream> 2 #include <vector> 3 #include <numeric> 4 #include <limits> 5 6 using namespace std; 7 8 int minTime=1e10; 9 int steps; 10 11 void travel(int intersections[][2], int roads[][3], int M, int N, int s, int t, int nowTime) 12 { 13 14 if( s==t ){ //抵达终点后 15 if (minTime > nowTime){ //剩余最大体力值存入全局变量Max 16 minTime = nowTime; 17 } 18 return; 19 } 20 if(steps == 0) 21 return; 22 23 int ori = nowTime; 24 for(int i = 0; i < M; i++){ 25 if(roads[i][0] == s){ 26 nowTime += roads[i][2]; 27 int tmp; 28 for(int j = 0; j < N; j++){ 29 if(intersections[j][0] == roads[i][1]){ 30 if( roads[i][1] != t ){ //未抵达终点,加上该路口等待时间 31 tmp = nowTime% (2*intersections[j][1]); 32 if( tmp >= intersections[j][1] ){ 33 nowTime += 2*intersections[j][1] - tmp; 34 } 35 } 36 break; 37 } 38 } 39 steps--; 40 travel(intersections, roads, M, N, roads[i][1], t, nowTime); 41 steps++; 42 nowTime = ori; 43 44 }else if(roads[i][1] == s){ 45 nowTime += roads[i][2]; 46 int tmp; 47 for(int j = 0; j < N; j++){ 48 if(intersections[j][0] == roads[i][0]){ 49 if( roads[i][0] != t ){ //未抵达终点,加上该路口等待时间 50 tmp = nowTime% (2*intersections[j][1]); 51 if( tmp >= intersections[j][1] ){ 52 nowTime += 2*intersections[j][1] - tmp; 53 } 54 } 55 break; 56 } 57 } 58 steps--; 59 travel(intersections, roads, M, N, roads[i][0], t, nowTime); 60 steps++; 61 nowTime = ori; 62 } 63 } 64 } 65 66 67 int main() { 68 int res; 69 70 int _N=9; 71 int _M=14; 72 int _s=0; 73 int _t=4; 74 75 int _intersections[][2]={{0,3},{1,5},{2,7},{3,3},{4,5},{5,7},{6,9},{7,3},{8,5}}; 76 int _roads[][3]={{0,1,4},{0,7,8},{1,2,8},{1,7,11},{2,3,7},{2,5,4},{2,8,2},{3,4,9},{3,5,14},{4,5,10},{5,6,2},{6,8,6},{6,7,1},{7,8,7}}; 77 78 steps = _M; 79 travel(_intersections, _roads, _M, _N, _s, _t, 0); 80 cout << minTime << endl; 81 82 return 0; 83 }