AOJ1194 Vampire

Vampire

Mr. C is a vampire. If he is exposed to the sunlight directly, he turns into ash. Nevertheless, last night, he attended to the meeting of Immortal and Corpse Programmers Circle, and he has to go home in the near dawn.

ある点 を端として決めると距離が決まる.Sample Input3を考えると下図のケースが最大である.

緑の線の長さは になるので,求めたい赤の線の長さが となる.建物が重なっている場所は一番大きい所を見て, が建物の角となり,その点を端として決めて一番短いものを答える.

Code

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
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <cmath>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<30
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int main() {
  int r, n;
  while(cin >> r >> n) {

      if(r == 0 && n == 0) break;

      vector<pair<int, P> > v(n);
      rep(i, n) cin >> v[i].second.first >> v[i].second.second >> v[i].first;

      int H[60], GETA = 30;
      memset(H, 0, sizeof(H));

      rep(i, n) {
          int h = v[i].first, x1 = v[i].second.first, x2 = v[i].second.second;

          REP(j, x1, x2) {
              H[j + GETA] = max(H[j + GETA], h);
          }
      }

      double ans = INF;
      REP(i, -r+1, r) {
          double res = r + min(H[i + GETA], H[i - 1 + GETA]);
          ans = min(ans, res - sqrt(r*r - i*i));
      }

      cout << fixed;
      cout.precision(4);
      cout << ans << endl;
  }

  return 0;
}
Mar 24th, 2016