CF1716B Permutation Chain 题解()

因为要使求得的排列链最长,所以我们可以先思考最长是多少。

因为排列链的固定性是向下递减,所以每次固定性减 \(1\) 所得的排列链肯定是最优情况。

所以我们考虑每次交换元素时令固定性只减 \(1\)。

那么在刚开始的操作中,要使排列链无序,那么就令任意两个元素交换其位置,为了方便后续操作,将 \(1\) 和 \(n\) 上面的元素进行交换。可以证明,交换这两个元素的固定性无论怎么样都是 \(-2\),因此在第一次交换时,固定性一定是 \(-2\),剩下的就拿 \(1\) 和其余位置上的元素交换,每次固定性 \(-1\),即有 \(n-1\) 次交换操作,加上初始的数列,即最长为 \(n\)。

#include <cstdio>
#include <iostream>

using namespace std;

int t,n,a[105];

int main() {
	scanf("%d",&t);
	while(t--) {
		scanf("%d",&n);
		printf("%d\n",n);
		for(int i=1;i<=n;i++) {//初始化
			a[i]=i;
			printf("%d ",a[i]);
		}
		printf("\n");
		int x=a[1];//交换1与n上的元素
		a[1]=a[n];
		a[n]=x;
		for(int i=1;i<=n;i++) {
			printf("%d ",a[i]);
		}
		puts(" ");
		int op=n;//记录1的位置
		for(int i=2;i<n;i++) {//2~n-1为a[i]=i的
			int x=a[i];
			a[i]=a[op];
			a[op]=x;
			op=i;//更新1的位置
			for(int j=1;j<=n;j++) printf("%d ",a[j]);
			printf("\n"); 
		}
	}
	return 0;
}
————————

因为要使求得的排列链最长,所以我们可以先思考最长是多少。

因为排列链的固定性是向下递减,所以每次固定性减 \(1\) 所得的排列链肯定是最优情况。

所以我们考虑每次交换元素时令固定性只减 \(1\)。

那么在刚开始的操作中,要使排列链无序,那么就令任意两个元素交换其位置,为了方便后续操作,将 \(1\) 和 \(n\) 上面的元素进行交换。可以证明,交换这两个元素的固定性无论怎么样都是 \(-2\),因此在第一次交换时,固定性一定是 \(-2\),剩下的就拿 \(1\) 和其余位置上的元素交换,每次固定性 \(-1\),即有 \(n-1\) 次交换操作,加上初始的数列,即最长为 \(n\)。

#include <cstdio>
#include <iostream>

using namespace std;

int t,n,a[105];

int main() {
	scanf("%d",&t);
	while(t--) {
		scanf("%d",&n);
		printf("%d\n",n);
		for(int i=1;i<=n;i++) {//初始化
			a[i]=i;
			printf("%d ",a[i]);
		}
		printf("\n");
		int x=a[1];//交换1与n上的元素
		a[1]=a[n];
		a[n]=x;
		for(int i=1;i<=n;i++) {
			printf("%d ",a[i]);
		}
		puts(" ");
		int op=n;//记录1的位置
		for(int i=2;i<n;i++) {//2~n-1为a[i]=i的
			int x=a[i];
			a[i]=a[op];
			a[op]=x;
			op=i;//更新1的位置
			for(int j=1;j<=n;j++) printf("%d ",a[j]);
			printf("\n"); 
		}
	}
	return 0;
}