hdu 5491 The Next(位操作)

19 篇文章 0 订阅

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5491

思路:

考虑通过比较当前的1的数目来进行最小的数的修正。

先将D加1,然后计算出D的1的数目tot,这时候比较tot和s1,s2的大小,这时候有两种情况:

1、tot<s1,这时我需要增加1的数目,因为要最小,所以我从右开始找到一个0(位置假设为i),将D加上2^i。

2、tot>s2,这时我需要减少1的数目,所以我从右开始找到一个1,将D加上2^i。

如此循环上述过程,直到符合tot符合s1,s2的条件。

上面操作的原因是:我加上2^i,就是将那一位由1变为0或者由0变为1,而我是从右边开始寻找的,可以保证每次所做的改变都是最小的。同时我的D是一直增加的,所以当条件满足时,就是那个最小的。

代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#define ll __int64
ll t,tot,s1,s2;
ll d[35],f;
ll getshu(ll x)
{
    ll num=0;
    t=0;
    while(x)
    {
        d[t++]=x%2;
        if(x%2)num++;
        x=x/2;
    }
    return num;
}
ll quickpow(int a,int b)
{
    ll ans=1;
    while(b)
    {
        if(b%2)ans=ans*a;
        a=a*a;
        b=b/2;
    }
    return ans;
}
int main()
{
    ll T,i,j,k,D,cases;
  cases=0;
    scanf("%I64d",&T);
    while(T--)
    {
        f=0;
        cases++;
        memset(d,0,sizeof(d));
        tot=0;
        t=0;
        scanf("%I64d%I64d%I64d",&D,&s1,&s2);
        ll y=D;
        y++;
      while(1)
      {
          tot=getshu(y);
          if(tot<s1)
          {
              for(i=0;i<t;i++)
              {
                  if(d[i]==0){
                    y+=1<<i;
                    break;
                  }
              }
          }
          else if(tot>s2)
          {
              for(i=0;i<t;i++)
              {
                  if(d[i]==1)
                  {
                      y+=1<<i;
                      break;
                  }
              }
          }
          else break;
      }
       printf("Case #%I64d: ",cases);
       printf("%I64d\n",y);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值