SRM310 D1E PyramidOfCubes

TopCoder Statistics - Problem Statement

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2010, TopCoder, Inc. All rights reserved.

$N$個のブロックをピラミッド状に並べていく.その時の表面積を答える.


上から見た時と下から見た時を考えると,必ず底面積分となる.後はそれぞれの段の横の面積を求めれば良い.
例えばSample1の場合,上段の横の面積は

の部分を数えるが,これは

の部分を数えても同じ.なので,上段の部分を囲うような長方形(正方形も含む)を探して数える.$幅が$その段数よりも少ない場合は横一列に並んでいる状態なので,別に考えて処理した.

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <queue>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define INF 1<<30
#define mp make_pair

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

class PyramidOfCubes {
  public:
  double surface(int K) {
      ll x = 1;
      ll sum = x * x;

      while(sum < K) {
          x++;
          sum += x * x;
      }

      double ans = 0.0;
      bool first = true;

      while(K) {
          if(K >= x * x) {
              if(first) {
                  ans += x * x * 2;
                  first = false;
              }

              K -= x * x;
              ans += x * 4;
              x--;
          } else {
              if(first) {
                  ans += K * 2;
                  first = false;
              }

              double res = INF;

              if(x <= K) {
                  REP(i, 1, x + 1) {
                      if(x * i >= K) {
                          res = min(res, double(i * 2 + x * 2));
                      }
                  }
              } else {
                  res = min(res, double(K * 2 + 2));
              }

              K = 0;
              ans += res;
          }
      }
      return ans;
  }
};
Sep 9th, 2016