forked from mpfeifer1/Kattis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathamsterdamdistance.cpp
65 lines (48 loc) · 1.55 KB
/
amsterdamdistance.cpp
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
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
ld inf = (ld)10000000000;
ll m, n;
ld r;
vector<int> dx = {1,-1,0,0};
vector<int> dy = {0,0,1,-1};
ld getdist(ll ax, ll ay, ll bx, ll by) {
ld straight = (r / n);
ld radius = ld(min(ay,by)) / n * r;
ld circ = ld(2) * M_PI * radius;
ld curved = (circ / 2) / m;
ld ans = straight * abs(ay-by) + curved * abs(ax-bx);
return ans;
}
int main() {
ll ax,ay,bx,by;
cin >> m >> n >> r;
cin >> ax >> ay >> bx >> by;
vector<vector<ld>> dist(m+1,vector<ld>(n+1,inf));
set<pair<ld,pair<int,int>>> q;
dist[ax][ay] = 0;
q.insert({0,{ax,ay}});
while(!q.empty()) {
pair<int,int> curr = q.begin()->second;
q.erase(q.begin());
for(int i = 0; i < 4; i++) {
pair<int,int> next = curr;
next.first += dx[i];
next.second += dy[i];
if(next.first < 0) continue;
if(next.second < 0) continue;
if(next.first > m) continue;
if(next.second > n) continue;
ld weight = getdist(curr.first,curr.second,next.first,next.second);
if(dist[next.first][next.second] > dist[curr.first][curr.second] + weight) {
q.erase({dist[next.first][next.second],next});
dist[next.first][next.second] = dist[curr.first][curr.second] + weight;
q.insert({dist[next.first][next.second],next});
}
}
}
cout << fixed;
cout.precision(8);
cout << dist[bx][by] << endl;
}