《怪物獵人崛起》大錘配裝指南
阿新 • • 發佈:2021-04-02
題目大意
給定這樣一個
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,
就可以使得上圖中, 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
*/