-
Notifications
You must be signed in to change notification settings - Fork 0
/
wall_construction.cc
129 lines (102 loc) · 2.78 KB
/
wall_construction.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
Copyright 2022 Ryan M. Jeong <[email protected]>
*/
// CP
#define CP do { \
std::ios::sync_with_stdio(false); \
std::cin.tie(NULL); \
} while (0)
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <cmath>
// iostream
using std::cin;
using std::cout;
using std::fixed;
// vector
using std::vector;
// utility
using std::pair;
// algorithm
using std::sort;
// cmath
using std::sqrt;
pair<int, int> starting_point;
bool CmpCoor(const pair<int, int>&,
const pair<int, int>&);
bool CmpCcw(const pair<int, int>&,
const pair<int, int>&);
int64_t CalcCcw(const pair<int, int>&,
const pair<int, int>&,
const pair<int, int>&);
int64_t CalcSqDist(const pair<int, int>&,
const pair<int, int>&);
int main() {
CP;
int n, r;
cin >> n >> r;
vector<pair<int, int>> v(n);
for (int i = 0; i < n; ++i)
cin >> v[i].first >> v[i].second;
sort(v.begin(), v.end(), CmpCoor);
starting_point = v.front();
sort(v.begin()+1, v.end(), CmpCcw);
vector<pair<int, int>> convex_hull;
for (const auto& p : v) {
while (convex_hull.size() >= 2) {
if (CalcCcw(convex_hull[convex_hull.size()-2], convex_hull.back(), p) > 0)
break;
convex_hull.pop_back();
}
convex_hull.push_back(p);
}
convex_hull.push_back(convex_hull.front());
// l = 2 * PI * r
double res = 3.14159265359 * 2 * r;
for (int i = 0; i < convex_hull.size() - 1; ++i) {
int64_t squared_dist = CalcSqDist(convex_hull[i+1], convex_hull[i]);
res += sqrt(static_cast<double>(squared_dist));
}
cout << fixed;
cout.precision(11);
cout << res;
return 0;
}
bool CmpCoor(const pair<int, int>& s,
const pair<int, int>& t) {
if (s.second < t.second)
return true;
if (s.second == t.second && s.first < t.first)
return true;
return false;
}
bool CmpCcw(const pair<int, int>& s,
const pair<int, int>& t) {
int64_t res = CalcCcw(starting_point, s, t);
if (res)
return res > 0; // ccw : true, cw : false
// res = 0
int64_t dist1 = CalcSqDist(s, starting_point);
int64_t dist2 = CalcSqDist(t, starting_point);
return dist1 < dist2;
}
/* ccw : pos.
on the line : 0
cw : neg. */
int64_t CalcCcw(const pair<int, int>& a,
const pair<int, int>& b,
const pair<int, int>& c) {
int64_t u1 = b.first - a.first;
int64_t v1 = b.second - a.second;
int64_t u2 = c.first - a.first;
int64_t v2 = c.second - a.second;
return u1 * v2 - u2 * v1;
}
int64_t CalcSqDist(const pair<int, int>& s,
const pair<int, int>& t) {
int64_t diff_x = s.first - t.first;
int64_t diff_y = s.second - t.second;
return diff_x * diff_x + diff_y * diff_y;
}