#gw2015i. [gw2015_i]ピラミッド - 立方体編

[gw2015_i]ピラミッド - 立方体編

問題文

伊織ちゃんのマイブームはピラミッドである。

伊織ちゃんは球状の石を使ったピラミッドに飽きてしまったため、今度は 11 辺の長さが 11 である立方体状の石を使ってピラミッドを作ることにした。伊織ちゃんは以下のような手順でピラミッドを作ることにした。

  • NtimesNN \\times N のマス目を紙に書く。各マスの 11 辺の長さは 11 である。i(1iN)i (1 ≦ i ≦ N) 行目 j(1jN)j (1 ≦ j ≦ N) 列目のマスをマス (i,j)(i,j) と呼ぶことにする。
  • 各マスに石を 11 個以上縦に積んで置く。マス (i,j)(i,j) には Hi,jH_{i,j} 個の石を積み上げる。
  • マスを 11 つ選ぶ。このマスをマス PP と呼ぶことにする。
  • いくつかの石(00 個でもよい)を取り除く。このとき、残った石が マス PP を中心としたピラミッド を構成していなければならない。

ただし、石がマス PP を中心としたピラミッドを構成している状態とは以下のような状態である。

  • マス PP をマス (Pi,Pj)(Pi,Pj)、マス (i,j)(i,j) に積まれている石の個数を Si,jS_{i,j}SPi,PjS_{Pi,Pj}TT と呼ぶことにすると、全ての i(1iN),j(1jN)i (1 ≦ i ≦ N), j (1 ≦ j ≦ N) に対して、以下の式が成り立っている。ただし、Abs(x)Abs(x)xx の絶対値を表すものとする。
    • $S_{i,j} = Max(0, T - Max(Abs(Pi - i), Abs(Pj - j)))$
    • Si,jMin(Pi,Pj,NPi+1,NPj+1)S_{i,j} ≦ Min(Pi, Pj, N - Pi + 1, N - Pj + 1)

このとき、マス PP に積まれている石の個数を ピラミッドの高さ と呼ぶことにする。

全ての i(1iN),j(1jN)i (1 ≦ i ≦ N), j (1 ≦ j ≦ N) に対して、マス (i,j)(i,j) を中心としたピラミッドを作るときにできるピラミッドの高さの最大値を求め、それらの和を答えよ。


入力

入力は複数のテストケースからなる。

テストケースの生成方法が少し特殊ですが、これは入力ファイルのサイズを削減するための措置であり、他に特に深い意味はありません。

入力は以下の形式で標準入力から与えられる。

NN QQ XX AA BB CC H1,1H_{1,1} H1,2H_{1,2} ... H1,NH_{1,N} H2,1H_{2,1} H2,2H_{2,2} ... H2,NH_{2,N} : HN,1H_{N,1} HN,2H_{N,2} ... HN,NH_{N,N}

  • 11 行目には、マス目の 11 辺の個数を表す整数 N(1N500)N (1 ≦ N ≦ 500) と、テストケース数を表す整数 Q(1Q10)Q (1 ≦ Q ≦ 10) が空白区切りで与えられる。
  • 22 行目には、44 つの整数 $X (0 ≦ X < C), A (0 ≦ A < C), B (0 ≦ B < C), C (N ≦ C ≦ 30,000)$ が空白区切りで与えられる。これらは、テストケースを生成する際の乱数を生成するために使われる整数である。
  • 33 行目からの NN 行には、最初に各マスに積む石の個数の情報が与えられる。このうち i(1iN)i (1 ≦ i ≦ N) 行目には、NN 個の整数が空白区切りで与えられる。このうち j(1jN)j (1 ≦ j ≦ N) 個目の整数 Hi,j(1Hi,jN)H_{i,j} (1 ≦ H_{i,j} ≦ N) はマス (i,j)(i,j) に積む石の個数を表す。

出力

出力は QQ 行からなる。このうち ii 行目には、ii 個目のテストケースに対する答えを出力せよ。出力の末尾にも改行を入れること。

ソースコードは以下のようなC言語風の疑似コードに沿って書けばよい。


int N, Q, X, A, B, C;
int H\[500\]\[500\];
int Rand() {
  return X = (A * X + B) % C;
}
void Shuffle() {
  for (int i = 0; i < N*N; ++i) {
    int ai = Rand() % N;
    int aj = Rand() % N;
    int bi = Rand() % N;
    int bj = Rand() % N;
    if (ai == bi && aj == bj) continue;
    swap(H\[ai\]\[aj\], H\[bi\]\[bj\]);
  }
}
void main() {
  入力を読み込む
  for (int i = 0; i < Q; i++) {
    この時点でのN,Hに対する答えを計算し、出力
    if (i != Q-1) Shuffle();
  }
  return 0;
}

入力例1


5 3
0 7 3 101
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1

出力例1


35
27
30

11 つ目のテストケースは以下のようになる。


1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1

このとき、各マスを中心としたピラミッドの高さの最大値は以下のようになる。


1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1

これらの和は 3535 であるため、出力の 11 行目には 3535 と出力する。

22 つ目のテストケースは以下のようになる。


2 1 2 1 1
2 1 1 1 1
1 2 1 1 1
2 2 1 1 1
1 2 1 3 2

このとき、各マスを中心としたピラミッドの高さの最大値は以下のようになる。


1 1 1 1 1
1 1 1 1 1
1 2 1 1 1
1 2 1 1 1
1 1 1 1 1

これらの和は 2727 であるため、出力の 22 行目には 2727 と出力する。

33 つ目のテストケースは以下のようになる。


1 1 1 2 1
2 1 1 2 1
1 1 3 1 1
1 2 2 2 2
2 1 1 1 1

このとき、各マスを中心としたピラミッドの高さの最大値は以下のようになる。


1 1 1 1 1
1 1 1 2 1
1 1 2 1 1
1 2 2 2 1
1 1 1 1 1

これらの和は 3030 であるため、出力の 33 行目には 3030 と出力する。