题目
题目大意
有一个
N
N
N层的数字金字塔如左图所示,最下面一层写了
2
N
−
1
2N-1
2N−1个数(这些数是
1
,
2
,
.
.
.
,
N
1,2,...,N
1,2,...,N的一个排列),然后用以下规则填满这个金字塔:
第
i
(
i
<
N
)
i(i<N)
i(i<N)行第
j
j
j个数为第
i
+
1
i+1
i+1行的第
j
−
1
j-1
j−1、
j
j
j、
j
+
1
j+1
j+1个数(即它左下、下、右下的数)的中位数。
现在给出金字塔的层数
N
N
N和顶端的数
X
X
X,问能否构造出底层的排列,如果可以,输出这个排列。
思路
我真的想问AtCoder出题人的脑洞有多大= =
这道题的解法越想越奇妙= =
首先,当
X
=
1
X=1
X=1或
X
=
2
N
−
1
X=2N-1
X=2N−1时无解(可以理解),其他情况均有解(见下面)。
你发现,只要在倒数第二行中部出现了一对
X
X
XX
XX基因?,那么顶端一定是
X
X
X,如图所示:
因为
X
,
X
,
a
X,X,a
X,X,a的中位数一定是
X
X
X。
于是做完了,你随便构造一下使倒数第二行中部有两个
X
X
X即可。
例如:
x
−
1
,
x
,
x
+
1
,
x
−
2
x-1,x,x+1,x-2
x−1,x,x+1,x−2(当
x
=
2
x=2
x=2的时候特殊处理一下)。
代码
极丑。
#include<cstdio>
int N,X;
int main(){
scanf("%d%d",&N,&X);
if(X==1||X==2*N-1)
return !puts("No");
puts("Yes");
if(N==2)
return !puts("1\n2\n3");
if(X==2){
for(int i=1;i<=N-2;i++)
printf("%d\n",4+i);
printf("3\n2\n1\n4\n");
for(int i=1;i<=N-3;i++)
printf("%d\n",N+2+i);
return 0;
}
int cnt=1;
for(int i=1;i<=N-2;i++){
if(cnt==X-2)
cnt=X+2;
printf("%d\n",cnt++);
}
printf("%d\n%d\n%d\n%d\n",X-1,X,X+1,X-2);
for(int i=1;i<=N-3;i++){
if(cnt==X-2)
cnt=X+2;
printf("%d\n",cnt++);
}
}