SRM303 D1E-D2M SpiralNumbers

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$番目は何列の何行目にあるかを答える.


枠を拡張していくように考えると,それぞれの枠の右上は平方数となるため,$t$段目の枠にあるかを調べるには $[(t-1) ^2, t ^2]$に挟まれているか見ればよい.後はその枠の四つ角に点を入れてその間にある場所を見つけて,そこから離れてる分足してあげれば良い.

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;

int dx[4] = {0, -1, 0, 1};
int dy[4] = {-1, 0, 1, 0};

string ans(ll y, ll x) {
  stringstream ss;
  ss << "(" << y << "," << x << ")";
  return ss.str();
}

class SpiralNumbers {
  public:
  string getPosition(int N) {
      if(N == 1) return ans(0, 0);

      ll l = 1, r = 1, t = 1;
      while(true) {
          if(l <= N && N <= r) break;
          t += 2;
          l = r + 1;
          r = t * t;
      }

      vector<ll> v(5);
      v[0] = t * t - 4 * (t - 1) + 1;
      v[1] = t * t - 3 * (t - 1);
      v[2] = t * t - 2 * (t - 1);
      v[3] = t * t - (t - 1);
      v[4] = t * t;

      vector<ll> y(5), x(5);
      y[0] = t / 2 - 1; x[0] = t / 2;
      y[1] = y[0] - (t - 2); x[1] = t / 2;
      y[2] = y[1]; x[2] = x[1] - (t - 1);
      y[3] = y[2] + t - 1; x[3] = x[2];
      y[4] = y[3]; x[4] = x[3] + (t - 1);

      ll R = 0, C = 0;
      rep(i, 4) {
          if(v[i] <= N && N <= v[i+1]) {
              ll cnt = N - v[i];
              R = y[i] + cnt * dy[i];
              C = x[i] + cnt * dx[i];
          }
      }

      return ans(-R, C);
  }

};
Aug 22nd, 2016