链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
Given two integers n,m\textstyle n,m, construct a permutation of length n that satisfies the following conditions.
-
There are exactly m subintervals of length 3 such that the numbers in these subintervals form a (non-degenerate) triangle.
输入描述:
Each test contains multiple test cases. The first line contains an integer T\textstyle TT (1≤T≤) — the number of test cases. The description of the test cases follows.
The first and only line of each test case contains two integers n andm (3≤n≤3×105, 0≤m≤n−2) — the length of permutation and the target subintervals.
It is guaranteed that the sum of n\textstyle n over all test cases does not exceed 3×.
输出描述:
For each test case, print one line.
If such a pair of permutations exists, print n integers pi, representing the permutation you have constructed. Otherwise, print “-1”.
示例1
输入
5 4 0 4 1 4 2 6 2 11 5
输出
3 1 2 4 1 2 3 4 -1 5 2 4 3 1 6 11 2 10 3 1 6 8 4 5 7 9
题目大意:构造一个长度为 n 的数组(数组里的值是 [ 1 , n ] 里的数且不重复),使得有 m 个长度为三的子区间,这些区间里的三个值看作三角形的三条边,并要满足构成三角形这个条件。
思路:因为有 1 这个值,它与任意两个值都不能构成三角形,所以 m=n-2 的时候输出 -1 。
先将这 n 个数倒序赋值给数组,这个时候的满足题意的个数是最多的时候,即 n - 3 个区间能构成三角形,以数组第 m 个数开始为分界线,分成两半,左边一半可以直接输出,右边一半还要处理,假如右边一半下标从 i = 1 开始记录,定义三个起点,分别用 a =(n-m)表示剩下数组中最大的数,b = a -ceil ( ( n - m )/3.0) 表示剩下数组中中等大小的数,c = 1 表示剩下数组中最小的数,先后输出 a , b , c 。 a ,b 出现过以后自减,c出现过以后自增,直至跑完数组。(放完第一轮之后就已经有m个区间满足题意,用 1 分割,1 后面的值必定不能构成三角形)。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int s[300005];
signed main()
{
IOS
int t;
cin >> t;
while(t--){
int n,m;
cin >> n >> m;
if(m==n-2){
cout << -1 << endl;
continue;
}
for(int i=1;i<=m;i++){
s[i]=n-i+1;
}
int a=n-m,b=a-ceil((n-m)/3.0),c=1;
for(int i=1;i+m<=n;i++){
if(i%3==0) s[i+m]=c,c++;
else if(i%3==1) s[i+m]=a,a--;
else s[i+m]=b,b--;
}
for(int i=1;i<=n;i++){
cout << s[i] << " ";
}
cout << endl;
}
return 0;
}