一、题目大意
给你一个数组 a=「1,2,...,n ,其中 n是多,还有一个整数 k。
你的任务是选择一个多的正整数 m 并将 a 分割成 m 个子数组 十。 b1,b2,...,bm 这样
·数组 a 中的每个元素正好属于一个子数组。
·对于所有的 1<i<m ,b;都是**个奇数,即每个子数组的长度都是奇数。
。median(median(b1),median(b2),...,median(bm))=k,即所有子数组的中位数数组的中位数#必须等于 k 。 median(c)表示数组 c 的中位数。
长度为 n 的数组 a 的一个子数组是某个整数 1≤l≤r≤n 的数组 al,al+1,……·,a」。
奇数长度数组的中位数是数组按非递减顺序排序后的中间元素。例如 median([1,2,5,4,3])=3median([3,2,1)=2,median(2,1,2,1,2,2,2)=2 .
输 入
每个测试由多个测试用例组成。第一行包含一个整数 t(1<t<5000 )- 测试用例数。测试用例说明如下。
每个测试用例的第一行包含两个整数 n 和 k(1<k<n<2.105kn ).
1<k<n<2·105,n 为多)--数组 a 的长度和所有子数组的中位数。
保证所有测试用例中 n 的总和不超过 2.105。
输出
对于每个测试用例:
如果没有合适的分区,则单行输出-1。
否则,在第一行输出一个零整数 m(1<m<n),在第二行输出 m 个不同的整数p1,p2,p3,······,pm( 1= p1 < p2 < p3 <...< pm<n )--表示每个子数组的左边界。
具体来说,对于有效答案
[p1,p2,…,pm]
b1=[ap1,ap1+1,…,ap2−1]
b2=[ap2,ap2+1,…,ap3−1]
……
bm=[apm,apm+1,…,an]
如果有多个解决方案,您可以输出其中任何一个。
二、思路:
注意题目不要求每部分的长度必须一致,只要是奇数就可以,所以如果我们如果只是一共就分成三部分,首先中间部分的中位数一定是k,我们可以预想第k个数前面共有k-1个数,第k个数后面一共有n-k个数;
当n=1的时候要单独判断,只需要输出k即可;
n不可能为偶数;
n为奇数的时候,
【第一部分有奇数个数k-1】+1+【第三部分有奇数个数n-k】==奇数个数n;
【第一部分有偶数个数k-1】+1+【第三部分有偶数个数n-k】==奇数个数n;
没有其他情况,其他情况的n都不是奇数
如果我们k是奇数的时候,这个时候不满足每部分都是奇数,k-1==偶数,n-k==偶数,于是我们把中间一个数k的子数组扩大,把第k-1和k+1加进来,这样k依旧是中位数,
注意这时,我们要确保k-1!=0同时n-k!=0,让每部分都有数,如果没有数则只有两部分了;
如果我们k是偶数的时候,这个时候满足第一部分有奇数个数,第二部分有1个数k,第三部分有奇数个数,只需要输出1,k,k+1即可。
三、具体实现代码:
#include <iostream>
using namespace std;
const int N = 1e5+10;
int t;
void solve()
{
int n,k;
cin>>n>>k;
if(n==1){
printf("1\n");
printf("%d\n",k);
return ;
}
int af=k-1,be=n-k;
if(af%2==1&&be%2==1){
cout<<3<<endl;
cout<<1<<' '<<k<<' '<<k+1<<endl;
}
else if(af%2==0&&be%2==0){
if(af!=0&&be!=0){
cout<<3<<endl;
cout<<1<<' '<<k-1<<' '<<k+2<<endl;
}
else
printf("-1\n");
}
else{
printf("-1\n");
}
}
int main(void){
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--){
solve();
}
return 0;
}