hdu5491

这道题我服了……
我是想模拟来着……
弄巧成拙了….
我一开始是想….

好吧我是程序员 坦白一点 这道题做起来没一点思路 看了别个的解题报告写的
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);
    }
}

你可能感兴趣的:(hdu5491)