1 条题解
-
0
解题思路:
计算在特定六边形网格布局下两点间的最短距离。先把笛卡尔坐标映射到六边形网格坐标,再结合网格特点算出网格内的最短路径,同时考虑两点到对应网格点的距离,综合得到最终最短距离。
分析:
1.贪心思想:在 tra 函数中,当将笛卡尔坐标转化为网格坐标时,对于每个初始映射得到的网格点,会遍历其周围六个相邻的网格点,计算每个相邻点到实际笛卡尔坐标点的距离,然后选择距离最近的网格点作为最终映射的网格坐标。这种每次都选择当前最优(距离最近)的选择,体现了贪心算法的思想,虽然这种局部最优选择不一定能保证全局最优,但在这个坐标映射的场景下,能得到一个较为合理的网格坐标表示。
2.距离计算:使用欧几里得距离公式 dis 函数计算两点间的直线距离,这是基础的几何计算。同时,在计算网格内两点间的距离时,充分利用了六边形的几何特性。例如,根据六边形的边长和角度关系(如 sin(pi/3) )计算出网格的垂直和水平间距,并且在 solve 函数中根据网格坐标的差值(水平和垂直方向)结合六边形的几何特性计算出网格内的路径长度。
实现步骤:
1.输入处理:持续读取六边形边长和两点的笛卡尔坐标,直至输入全为 0。
2.初始化:算出六边形网格的垂直和水平间距,将笛卡尔坐标转为初始网格坐标,优化网格坐标。
3.距离计算:若两点网格坐标相同,直接返回直线距离;否则,算出网格坐标差值,结合网格几何特性算出网格内距离,再加上两点到对应网格点的距离。
4.输出结果:以保留三位小数的形式输出最短距离。
c++实现:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #define max(a,b) ((a)>(b)?(a):(b)) const double pi = acos(-1.0); const int d[6][2] = {{0, 2}, {0, -2}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; double l, xa, ya, xb, yb, hd, wd; int xan, yan, xbn, ybn; double dis(double x1, double y1, double x2, double y2) { return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); } void tra(int &x, int &y, double xa, double ya) { if (x % 2) { if (y % 2 == 0) { y++; } } else { if (y % 2) { y++; } } int minx = x, miny = y; double mind = dis(x * wd, y * hd, xa, ya); for (int i = 0; i < 6; i++) { double xx = (d[i][0] + x) * wd; double yy = (d[i][1] + y) * hd; if (mind > dis(xx, yy, xa, ya)) { minx = d[i][0] + x; miny = d[i][1] + y; mind = dis(xx, yy, xa, ya); } } x = minx; y = miny; } void init() { hd = sin(pi/3) * l; wd = l + l / 2; xan = xa / wd; yan = ya / hd; xbn = xb / wd; ybn = yb / hd; tra(xan, yan, xa, ya); tra(xbn, ybn, xb, yb); } double solve() { if (xan == xbn && yan == ybn) return dis(xa, ya, xb, yb); int xx = abs(xbn - xan), yy = abs(ybn - yan); double ans = dis(xa, ya, xan * wd, yan * hd) + dis(xb, yb, xbn * wd, ybn * hd) + xx * sin(pi/3) * 2 * l; if (yy > xx) ans += (yy - xx) * l * sqrt(3) / 2; return ans; } int main() { while (~scanf("%lf%lf%lf%lf%lf", &l, &xa, &ya, &xb, &yb) && l || xa || ya || xb || yb) { init(); printf("%.3lf\n", solve()); } return 0; }
- 1
信息
- ID
- 519
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 15
- 已通过
- 1
- 上传者