#gw2015i. [gw2015_i]ピラミッド - 立方体編
[gw2015_i]ピラミッド - 立方体編
问题
伊织酱的新宠是金字塔。
因为伊织酱厌倦了使用球形石头堆成的金字塔,所以他决定用边长为1的立方体状石头来建造金字塔。伊织酱按照以下步骤来建造金字塔。
- 在一个 的网格纸上画出网格。每个格子的边长为1。我们将第 行第 列的格子称为格子 。
- 在每个格子里面至少放置一个石头。将 个石头堆叠在格子 上。
- 选择一个格子。这个格子我们称之为格子 。
- 移除一些石头(可以是0个)。这时,剩余的石头必须构成以格子 为中心的金字塔。
但是,石头构成了以格子 为中心的金字塔的条件如下:
- 假设将格子 称为 ,将格子 上的石头个数称为 ,将 称为 ,对于所有 ,以下等式成立。这里, 表示 的绝对值。
- $S_{i,j} = Max(0, T - Max(Abs(Pi - i), Abs(Pj - j)))$
这时,我们称格子 上的石头个数为 金字塔的高度。
对于所有 ,求出以格子 为中心建造金字塔时可能达到的最大高度,然后将这些最大高度求和并输出。
输入
输入包含多个测试用例。
(生成测试用例的方法有点特殊,这是为了减小输入文件的大小,没有其他特别深刻的意义。)
输入格式如下,从标准输入中读取:
... ... : ...
- 第一行包含两个整数 和 ,分别表示网格的边长和测试用例的数量。
- 第二行包含四个整数 $X (0 \leq X < C), A (0 \leq A < C), B (0 \leq B < C), C (N \leq C \leq 30,000)$,用空格分隔。这些整数用于生成测试用例时使用的随机数。
- 接下来的 行给出了每个格子中初始放置的石头数量。其中第 行()包含了 个以空格分隔的整数,其中第 个整数 表示格子 中放置的石头数量。
输出
输出包含 行。其中第 行表示第 个测试用例的答案。输出末尾包含换行符。
你可以根据以下类似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
第一个测试用例的网格如下:
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
这些最大高度的和为35,因此输出的第一行为35。
第二个测试用例的网格如下:
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