题目大意
给定这样一个
n
n
n 层的方格金字塔:
然后最后一行是
1
∼
n
×
2
−
1
1\sim n\times 2-1
1∼n×2−1 的排列,之后每一格都是正下方、左下方、右下方
3
3
3 个格子中的数的中位数。
然后给定第一层的数 x x x,要求你构造一个合法的最后一层。
Solution
显然不可能枚举然后验证,那么这显然是一道构造题(阿巴阿巴)
首先观察它构造的规律。如果三个数中,有 2 2 2 个是相等的,那么这三个数“合成”的数也一定是与那两个数相等。所以在任意位置,一旦有 2 2 2 个相邻的并且相等的数,那么这两个数所在的列一定都是这个数。
即:
所以,为了使得第一层的那个唯一的数是
x
x
x,最简单的构造就是把上图中黄色的一列构造成
x
x
x。
可是最后一层并不是上图那么美好,而是 1 ∼ n × 2 − 1 1\sim n\times 2-1 1∼n×2−1 的排列诶。所以就需要构造。
首先把最后一层中间填上
x
x
x,如图:
此时,只需要满足:
- A > x A>x A>x 且 B , C < x B,C<x B,C<x \qquad 构造一
- 或 A < x A<x A<x 且 B , C > x B,C>x B,C>x \qquad 构造二
就可以使得上图中, x x x 和 A A A 的上方都被强迫构造成 x x x。
此时,还余留亿点点问题。
首先是上面两种构造选哪种,是等价的吗?
显然不是,如果
x
=
2
x=2
x=2 ,那么就没有
2
2
2 个数比
2
2
2 要小,就无法用上述中第一种构造法。同理,
x
=
n
×
2
−
2
x=n\times 2-2
x=n×2−2 时就不能用第二种。
其次,什么时候是无解的。
这不能再简单了,就是
1
1
1 或者
n
×
2
−
1
n\times 2-1
n×2−1 是无解的。因为这俩连一个比它小(大)的都没有。
Code
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int MAXN=2e5+10;
bool vis[MAXN];
int ans[MAXN];
int main()
{
int n,x;
scanf("%d%d",&n,&x);
if(x==1||x==2*n-1){puts("No");return 0;}//先判无解,白给
if(x==2){//我选择特判2,但是相信你一定知道如果特判n*2-2也是可以的
//如果是2,那么不能用第一种构造
puts("Yes");
ans[n+1]=1;
ans[n]=2;
ans[n-1]=2*n-1;
ans[n+2]=2*n-2;
for(int i=1,j=3;i<=n-2;i++,j++)
ans[i]=j;
for(int i=n*2-1,j=2*n-3;i>=n+3;i--,j--)
ans[i]=j;
for(int i=1;i<=n*2-1;i++)
printf("%d\n",ans[i]);
}else{//同理
puts("Yes");
ans[n]=x;vis[x]=1;
ans[n+1]=2*n-1;vis[2*n-1]=1;
ans[n-1]=1;vis[1]=1;
ans[n+2]=2;vis[2]=1;
for(int i=1,j=1;i<=n*2-1;i++,j++){
while(ans[i]) i++;
while(vis[j]) j++;
ans[i]=j;
}
for(int i=1;i<=n*2-1;i++)
printf("%d\n",ans[i]);
}
}
/*这是用我的代码的样例1的输出~
4
444
34446
3514726
*/