您的位置:首页 > Web前端

【HDU】5491 The Next(2015 ACM/ICPC Asia Regional Hefei Online)

2016-07-12 10:13 441 查看

The Next

题目链接

The Next

题目大意

规定一种数叫做WYH数,其二进制中1的个数在s1,s2之间,现在给你一个WYH数,要你求比他大的WYH数中最小的一个(就是下一个WYH数)

题解

构造

其实这一题挺有意思的…

考虑比D大1的数D+1,先算出D+1中1的个数L,然后分情况讨论:

如果L大于S2

因为我们现在要减少1的个数,而且我们现在只能加,所以考虑二进制中的最后一个1,只有让这一位向前进位,我们才能减少1的个数,所以对于这种情况,我们先找出最后一个1所在的位置,然后把该位的1向前进位。

如果L小于S1

这个好说,我们从二进制的最右边向左边扫,把遇到的0全部变成1,知道满足条件为止。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#define LL long long

using namespace std;

int T,s1,s2;
LL d;

int num(LL a)
{
int ans=0;
for (int i=0;i<32;i++) if ((1<<i)&a) ans++;
return ans;
}

int main()
{
int Case=1;
scanf("%d",&T);
while (T--)
{
scanf("%I64d%d%d",&d,&s1,&s2);
d++;
int l=num(d);
printf("Case #%d: ",Case++);
if (l>=s1 && l<=s2)
{
printf("%I64d\n",d);
continue ;
}
while (1)
{
if (l<s1)
{
for (int i=0;i<32;i++)
if (((1<<i)&d)==0)
{
d=d|(1<<i);
l++;
if (l==s1) break;
}
printf("%I64d\n",d);
break;
}
if (l>s2)
{
for (int i=0;i<32;i++) if ((1<<i)&d)
{
d+=(1<<i);
break;
}
l=num(d);
if (l>=s1 && l<=s2)
{
printf("%I64d\n",d);
break;
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: