[构造][打表]Link with Monotonic Subsequence 2022牛客多校第2场 G

11 篇文章 0 订阅
3 篇文章 0 订阅

题目描述

First, let's review some definitions. Feel free to skip this part if you are familiar with them.
A sequence aaa is an increasing (decreasing) subsequence of a sequence bbb if aaa can be obtained from bbb by deletion of several (possibly, zero or all) elements and all elements are in increasing (decreasing) order from the beginning to the end.
A permutation is an array consisting of nnn distinct integers from 111 to nnn in arbitrary order. For example, [2,3,1,5,4][2,3,1,5,4][2,3,1,5,4] is a permutation, but [1,2,2][1,2,2][1,2,2] is not a permutation (222 appears twice in the array) and [1,3,4][1,3,4][1,3,4] is also not a permutation (n=3n=3n=3 but there is 444 in the array).
The problem starts from here.
Link has an array. He is currently learning the longest increasing subsequence algorithm. So he comes up with the following question.
Let the value of a permutation ppp be max⁡(lis(p),lds(p))\max({\rm lis}(p),{\rm lds}(p))max(lis(p),lds(p)), where lis(p){\rm lis}(p)lis(p) is the length of the longest increasing subsequence of ppp and lds(p){\rm lds}(p)lds(p) is the length of the longest decreasing subsequence of ppp. For all permutations of length nnn, which one has the minimum value?

输入描述:

Each test contains multiple test cases. The first line contains the number of test cases T(1≤T≤1000)T(1\le T \le1000)T(1≤T≤1000).

For each test case, there is only one line, containing an integer n(1≤n≤106)n(1 \leq n \leq 10^6)n(1≤n≤106).

It is guaranteed that the sum of nnn over all test cases does not exceed 10610^6106.

输出描述:

For each test case, output a single line containing a permutation of length nnn.

If there are multiple answers, print any of them.

示例1

输入

3
1
2
3

输出

1
1 2
1 3 2

题意: 给出n,要求构造出一个长度为n的全排列,满足该全排列的max( 最长上升子序列长度,最长下降子序列长度 )最小。

分析: 一开始刚看到这题是想着随便找找规律构造几个特殊的全排列,后来发现之前构造的是错的,于是可以写一个打表,把符合要求的全排列都打出来,通过打表可以发现这个题目要求的值与根号n有关,也就是说LIS和LDS长度均小于等于根号n上取整,所以根据这点可以猜想出来一种构造方法,那就是按照根号n来分块,每块长度为根号n,块内就是一个递减序列,块间构成递增序列,以n = 9为例就是这样的:3 2 1 6 5 4 9 8 7。

具体代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
using namespace std;

signed main()
{
	int T;
	cin >> T;
	while(T--){
		int n;
		scanf("%d", &n);
		int t = ceil(sqrt(n));
		vector<int> a;
		int top = n;
		for(int i = 1; i <= n; i++){
			a.push_back(top--);
			if(a.size() == t){
				for(int j = a.size()-1; j >= 0; j--)
					printf("%d ", a[j]);
				a.clear();
			}
		}
		for(int j = a.size()-1; j >= 0; j--)
			printf("%d ", a[j]);
		puts("");
	} 
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值