您的位置:首页 > 其它

HDU 5491 The Next(构造数)

2015-10-02 17:58 323 查看
题目地址:点击打开链接

题意:给一个数D,然后给一个范围[S1,S2],求一个比D大的,化为2进制数里面1的个数满足范围的,最小的数

思路:参考大神思想,暴力超时,不管你求一个数化为2进制数里面1的个数的方法多么巧妙,思想是找规律,构造数,如果1的个数小于S1,则找到最右面的0位,把它变为1,如果1的个数大于S2,则找到最右面的1位,把它变为0,特例如D=15,S1=4,S2=5,也符合,构造的数会超int,用long long

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

using namespace std;

const int maxn = 40;
int digital[maxn];

int main()
{
int t,s1,s2,i,j;
int cas = 1;
long long m,d;
scanf("%d",&t);
while(t--)
{
scanf("%I64d%d%d",&d,&s1,&s2);
d++;
while(1)
{
int wei = 0,sum = 0;
m = d;
while(m)
{
digital[wei++] = m & 1;
if(m & 1)
sum++;
m /= 2;
}
if(sum < s1)
{
for(i=0; i<wei; i++)
{
if(digital[i] == 0)
{
j = i;
break;
}
}
d += 1<<j;
}
else if(sum > s2)
{
for(i=0; i<wei; i++)
{
if(digital[i] == 1)
{
j = i;
break;
}
}
d += 1<<j;
}
else
break;
}
printf("Case #%d: %I64d\n",cas++,d);
}
}

大神地址:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: