这道题我服了……
我是想模拟来着……
弄巧成拙了….
我一开始是想….
好吧我是程序员 坦白一点 这道题做起来没一点思路 看了别个的解题报告写的
TAT
QAQ
其实思想很简单 就是你要求的是比n大的数 首先加1 如果1的个数sum大于s2 那么你就想办法去掉一个数
找到最低位的1 变成0 重点来了 也是卡住我的地方 最低位的1 变成0 其实就是加上(1<<(i-1))这个数 因为你加上这个数 这一位会变成0
有人问了 那这个数不是会很大吗?
我们要求的数 本来就要比n大 大多少呢 要根据题目s1 s2的数据决定 现在你的数目要比s2大 所以你要少一个1 才行 但是怎么办呢 直接去掉? 不行 那你的数可能会比n小 所以你只能加上最低位1 的这个数
(1<<(i-1)) 这样也可以保证你求的数是比n大的数中最小的
那要是sum比s1还小呢 不是同样的道理吗?
#include<cstdio>
#include<cstring>
typedef long long ll;
ll get(ll x){
ll sum=0;
while(x){
if(x&1)sum++;
x>>=1;
}
return sum;
}
ll min(ll a_,ll b_){
return a_>b_?b_:a_;
}
int main(){
int T;
scanf("%d",&T);
int coun__=1;
while(T--){
ll n;
ll x,y;
scanf("%lld%lld%lld",&n,&x,&y);
printf("Case #%d: ",coun__++);
ll ans=n+1;
while(1){
ll sum=get(ans);
if(sum>y){
ll k=0,temp_=ans;
while(temp_){
if(temp_&1){ans+=(1<<k);break;}
k++;
temp_>>=1;
}
}
else if(sum<x){
ll k=0,temp_=ans;
while(temp_){
if(!(temp_&1)){ans+=(1<<k);break;}
k++;
temp_>>=1;
}
}
else break;
}
printf("%lld\n",ans);
}
}