这道题想了挺久的
题解
我们都知道1,2,4,8,...,2^n 能刚好凑出1~中的所有数
要想刚好凑出1~n(<=n<
)中所有的数,则可以用1,2,...
以及
,其中有些数可能会由两种不同的组合凑出来,但是能凑出来的数一定在1~n的范围内
思考: 一种可能能行的方法:假设先有数1,2..2^(m-2)可以凑出1~
中的所有数,数列中不能有
,有的话范围到了1~
包含了k,不符合题意,所以数列中的下一个数为
,就可刚好凑出1~k-1中的所有数,当时首先设想之后的数为
直到数列凑够25个数,但是有个问题就是数列1,2..2^(m-2),k-(2^m-1)-1可以凑出1~k-1中的所有数,数列中再加上一个2^m,则能凑出的数的范围变为了1~k-1∪2^m~k-1+2^m,其中k+1~2^m-1范围内的数不能被凑出来,所以不可行.
再思考在k-(2^m-1)-1后面数列加上一个数k+1, 1,2...2^(m-2),k-(2^m-1)-1可以凑出1~k-1,再加上k+1,就可以凑出1~k-1与k+1~2k,数列后面再有,就能够实现范围的无缝衔接(因为k>=2^m,所以2k>=2^(m+1)),但是又发现了一个致命的问题 1,2...2^(m-2),k-(2^m-1)-1,k+1可以凑出1~2k(不包含k),再加上2^m并不能凑出1~2^(m+1)-1中的所有数,因为1,2...2^(m-2),k-(2^m-1)-1,k+1凑出的数不包含k,则加上2^m后的范围就不包含k+2^m,数列中再加上2^(m+1),范围内的数凑不出来k,2^m+k,2^(m+1)+k,2^m+k+2^(m+1),以此类推 1,2...2^(m-2),k-(2^m-1)-1,k+1凑出来的数不包含k而导致了一系列问题,一些与k相关的数并不能凑出来
最终解决办法:首先一样前面的数列为1,2...2^(m-2),k-(2^m-1)-1可以凑出来1~k-1,然后数列加上一个数据k+1则可以凑出来1~k-1∪k+1~2k 数列中再加上数据2k+1,则可以凑出来1~k-1∪k+1~4k+1,但是不包含3k+1, 数列中再加上数3k+1,则可以凑出来1~k-1∪k+1~7k+2其中凑不出来6k+2, 则数列中加上6k+2 凑不出来12k+4, 以此类推,除了前两个数都是前一个数的二倍,凑出来25个数
代码
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int a[50];
int main(){
int T;
cin>>T;
while(T--){
int n,k;
cin>>n>>k;
int cnt=1;
int sum=0;
int t=1;
if(k==1){
a[1]=2;
a[2]=3;
cnt=3;
sum=5;
t=4;
}
while(cnt<=25){
if(sum<k&&sum+t>=k){
// cout<<k<<' '<<sum<<endl;
a[cnt]=k-sum-1;
sum+=a[cnt];
cnt++;
a[cnt]=k+1;
sum+=a[cnt];
cnt++;
a[cnt]=2*k+1;
cnt++;
t=3*k+1;
break;
}else if(t>a[cnt-1]){
a[cnt]=t;
sum+=a[cnt];
cnt++;
}
t*=2;
}
while(cnt<=25){
a[cnt++]=t;
t*=2;
}
cout<<25<<endl;
for(int i=1;i<=25;i++)cout<<a[i]<<' ';
cout<<endl;
}
}