题干
题意:
输入 x ,使得 x 一直减某个数值 一直减到 1,所减的这个数值不能出现两次,输出该过程 x 的变化情况。
思路:
我们可以反过来想,使得 1 累加到 x ,所累加的这个中间数值不能出现两次,其次我们可以利用 倍增的关系,这样可以使得 所累加的这个中间数值不会出现两次,其次,当我们倍增的时候,肯定会到达某个峰值 使得恰好越过了 目标 x ,所以我们也要注意往回退。
代码详解如下:
#include <bits/stdc++.h>
#define pb push_back
#define YES cout<<"YES"<<'\n';
#define NO cout<<"NO"<<'\n';
using namespace std;
using ll = long long;
void solve()
{
ll x;cin>>x;
stack<ll>ans;//逆向输出
ll now=1;//当前数值
ll add=1;//添加值
ans.push(1);
while(now!=x)
{
if(now+add<=x)
{
now+=add;
add<<=1;
ans.push(now);//添加变化情况
}
else
{
add>>=1;//不满足,开始缩小
}
}
cout<<ans.size()<<'\n';
while(ans.size()!=0)
{
cout<<ans.top()<<' ';
ans.pop();
}
cout<<'\n';
}
int main()
{
cin.tie(0);
cout.tie(0);
ios_base::sync_with_stdio( false );
ll t;cin>>t;
while(t-- )
solve();
return 0;
}