原题链接:算法集训队第二场考核赛_C.掌门人打桩
C.掌门人打桩
题目背景
传说在艾泽拉斯的潘达利亚,影踪派的掌门人祝踏岚擅于打桩,有着影踪派自家的一套绝学。
题目描述
来自暴风城远征队的你拜影踪派掌门为师。你发现,影踪寺里总共有 N N N 个圆柱体桩头,它们都是垂直摆放的,且半径都为 R R R 。现在,掌门人祝踏岚要求你弄一条定长的细线来将这些圆柱体绑一圈,求最短需要的细线长度(不计细绳直径)。
输入描述
第 1 1 1 行输入两个数:整数 N N N 和实数 R R R。
接下来的 N N N 行中按逆时针序给出这 N N N 个圆柱形桩头中心的横纵坐标,其中,坐标的绝对值不超过 100 100 100 。输出描述
输出绳子的长度,精确到小数点后 2 2 2 位。
输入输出样例
输入 #1:
2 1 0.0 0.0 2.0 0.0
输出 #1:
10.28
输入 #2:
4 2 0.0 0.0 2.0 0.0 2.0 2.0 0.0 2.0
输出 #2:
20.57
说明/提示:
【数据范围】
圆周率取值: 3.1415926 3.1415926 3.1415926;
1 ≤ N ≤ 100 1 \leq N \leq 100 1≤N≤100。
解决办法:
显而易见,当绕成的细线处在同一个水平面时,即为最短长度。因此,可以将本题从三维问题化简为二维问题,即在一个水平面上将几个柱子绑一圈。
如图所示为两个圆的情况,两点之间线段最短,因此将绳子“拉直”后相连为最短的情况,即红色部分。将红色的两个半圆拼接成一个圆的周长,再加上上下两条直线的周长,即为答案:
a
n
s
=
2
∗
(
x
1
−
x
2
)
2
+
(
y
1
−
y
2
)
2
+
2
Π
R
ans = 2 *\sqrt {(x_1 -x_2)^2 + (y_1 - y_2)^2} + 2ΠR
ans=2∗(x1−x2)2+(y1−y2)2+2ΠR
参考代码:
#include<iostream>
#include<iomanip>
#include<cstring>
#include<math.h>
using namespace std;
#define PI = 3.1415926;
double x[1000], y[1000],R;
double ans = 0;
int main() {
int N;
cin >> N >> R;
cin >> x[1] >> y[1];
for (int i = 2; i <= N; i++)
{
cin >> x[i] >> y[i];
ans += 1.0 * sqrt(pow(x[i] - x[i - 1], 2) + pow(y[i] - y[i - 1],2));
}
ans += 1.0 * sqrt(pow(x[N] - x[1], 2) + pow(y[N] - y[1], 2)) + 2.0 * R * 3.1415926;
printf("%.2lf", ans);
return 0;
}