题目地址:
https://www.acwing.com/problem/content/1125/
随着白天越来越短夜晚越来越长,我们不得不考虑铲雪问题了。整个城市所有的道路都是双向车道,道路的两个方向均需要铲雪。因为城市预算的削减,整个城市只有 1 1 1辆铲雪车。铲雪车只能把它开过的地方(车道)的雪铲干净,无论哪儿有雪,铲雪车都得从停放的地方出发,游历整个城市的街道。现在的问题是:最少要花多少时间去铲掉所有道路上的雪呢?
输入格式:
输入数据的第
1
1
1行表示铲雪车的停放坐标
(
x
,
y
)
(x,y)
(x,y),
x
,
y
x,y
x,y为整数,单位为米。下面最多有
4000
4000
4000行,每行给出了一条街道的起点坐标和终点坐标,坐标均为整数,所有街道都是笔直的,且都是双向车道。铲雪车可以在任意交叉口、或任何街道的末尾任意转向,包括转
U
U
U型弯。铲雪车铲雪时前进速度为
20
20
20千米/时,不铲雪时前进速度为
50
50
50千米/时。保证:铲雪车从起点一定可以到达任何街道。
输出格式:
输出铲掉所有街道上的雪并且返回出发点的最短时间,精确到分钟,四舍五入到整数。输出格式为”hours:minutes”,minutes不足两位数时需要补前导零。
数据范围:
−
1
0
6
≤
x
,
y
≤
1
0
6
−10^6≤x,y≤10^6
−106≤x,y≤106
所有位置坐标绝对值不超过
1
0
6
10^6
106。
因为每条路都是双向的,可以看成是个有向图,并且每条边都有对应的反向边,于是每个顶点的入度必然等于出度,所以存在欧拉回路(题目有提图是连通的)。那么最少花费时间就是所有边(包括去边和回边)的总长度除以速度。代码如下:
#include <iostream>
#include <cmath>
using namespace std;
int main() {
double x1, y1, x2, y2;
// 起点没有用
cin >> x1 >> y1;
double sum = 0;
while (cin >> x1 >> y1 >> x2 >> y2) {
double dx = x1 - x2, dy = y1 - y2;
sum += sqrt(dx * dx + dy * dy);
}
// 这样要乘以2
int min = round(sum * 2 / 1000 / 20 * 60);
int hour = min / 60;
min %= 60;
printf("%d:%02d\n", hour, min);
return 0;
}
时间复杂度 O ( E ) O(E) O(E),空间 O ( 1 ) O(1) O(1)。