1. 程式人生 > 遊戲攻略 >《怪物獵人崛起》大錘配裝指南

《怪物獵人崛起》大錘配裝指南

AT2163

題目大意

給定這樣一個 n n n 層的方格金字塔:
在這裡插入圖片描述
然後最後一行是 1 ∼ n × 2 − 1 1\sim n\times 2-1 1n×21 的排列,之後每一格都是正下方、左下方、右下方 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 1n×21 的排列誒。所以就需要構造。

首先把最後一層中間填上 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×22 時就不能用第二種。

其次,什麼時候是無解的。
這不能再簡單了,就是 1 1 1 或者 n × 2 − 1 n\times 2-1 n×21 是無解的。因為這倆連一個比它小(大)的都沒有。

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
*/

The end