求d的最小增量,注意为0的特判,以及1的个数不能改变的情况,然后其他情况找到最小的位0的位置变成1,然后
根据s1的大小去改变后面的1就行,具体的看代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<cmath>
#include<cctype>
#include<queue>
#define LL long long
using namespace std;
const double eps=1e-10;
const double pi=acos(-1.0);
int main()
{
int t;
cin>>t;
int cas=0;
while(t--)
{
LL d,s1,s2;
scanf("%lld%lld%lld",&d,&s1,&s2);
int a[40];
memset(a,0,sizeof(a));
LL cnt=0;
LL tem=d;
LL it=0;
while(tem)
{
if(tem%2)
it++;
a[cnt]=tem%2;
tem/=2;
cnt++;
}
// for(int i=0;i<cnt;i++)
// cout<<a[i];
// cout<<endl;
// cout<<it<<endl;
LL tem1=0;
// cout<<tem1<<endl;
if(d==0)
{
printf("Case #%d: %lld\n",++cas,d+1);
continue;
}
if(d%2==0)
{
if(it!=s2)
{
printf("Case #%d: %lld\n",++cas,d+1);
continue;
}
else
{
while(!a[tem1]) tem1++;
while(a[tem1]) tem1++;
a[tem1]=1;
if(tem1==cnt)
cnt++;
tem1--;
a[tem1]=0;
int t1=0;
for(int i=0;i<tem1;i++)
if(a[i])
{
t1++;
a[i]=0;
}
if(it>s1)
t1=s1-(it-t1);
for(int i=0;i<t1;i++)
a[i]=1;
}
}
else
{
int tem1=0;
while(a[tem1]) tem1++;
a[tem1]=1;
if(tem1==cnt)
cnt++;
tem1--;
if(tem1>=0)
a[tem1]=0;
int t1=0;
for(int i=0;i<tem1;i++)
if(a[i])
{
t1++;
a[i]=0;
}
// cout<<it<<s1<<t1<<endl;
if(it>s1)
t1=s1-(it-t1);
for(int i=0;i<t1;i++)
a[i]=1;
}
LL tem2=1;
LL sum=0;
for(int i=0;i<cnt;i++)
{
if(a[i])
sum+=tem2;
tem2=(tem2<<1);
}
printf("Case #%d: %lld\n",++cas,sum);
}
return 0;
}