HDU5491 The Next 字符串+位模拟+思维

25 篇文章 0 订阅
1 篇文章 0 订阅

1.题目描述:

The Next

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2024    Accepted Submission(s): 732


Problem Description
Let  L  denote the number of 1s in integer  D ’s binary representation. Given two integers  S1  and  S2 , we call  D  a WYH number if  S1LS2 .
With a given  D , we would like to find the next WYH number  Y , which is JUST larger than  D . In other words,  Y  is the smallest WYH number among the numbers larger than  D . Please write a program to solve this problem.
 

Input
The first line of input contains a number  T  indicating the number of test cases ( T300000 ).
Each test case consists of three integers  D S1 , and  S2 , as described above. It is guaranteed that  0D<231  and  D  is a WYH number.
 

Output
For each test case, output a single line consisting of “Case #X: Y”.  X  is the test case number starting from 1.  Y  is the next WYH number.
 

Sample Input
  
  
3 11 2 4 22 3 3 15 2 5
 

Sample Output
  
  
Case #1: 12 Case #2: 25 Case #3: 17
 

Source
 

Recommend
wange2014   |   We have carefully selected several similar problems for you:   6014  6013  6012  6011  6010 
2.题意概述:

T组测试数据。
L,S1,S2。
L的二进制中有x个1,x满足  S1<=x<=S2
求满足S1<=x<=S2的下一个数。

3.解题思路:

考虑通过比较当前的1的数目来进行最小的数的修正。
先将D加1,然后计算出D的1的数目tot,这时候比较tot和s1,s2的大小,这时候有两种情况:
1、sum<s1,这时我需要增加1的数目,因为要最小,所以我从右开始找到一个0(位置假设为i),将D加上2^i。
2、sum>s2,这时我需要减少1的数目,所以我从右开始找到一个1,将D加上2^i。
如此循环上述过程,直到符合sum符合s1,s2的条件。
上面操作的原因是:我加上2^i,就是将那一位由1变为0或者由0变为1,而我是从右边开始寻找的,可以保证每次所做的改变都是最小的。同时我的D是一直增加的,所以当条件满足时,就是那个最小的。

(好像这题还有个新姿势,就是lowbit,以后补上解法)

4.AC代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define maxn 40
using namespace std;
typedef long long ll;
char d[maxn];
ll T, D, cnt, s1, s2, kase = 0;
ll getbinary(ll x)
{
	ll num = 0, t = 0;
	while (x)
	{
		d[t++] = x % 2;
		if (x & 1)
			num++;
		x /= 2;
	}
	return num;
}
int main()
{
	scanf("%lld", &T);
	while (T--)
	{
		memset(d, 0, sizeof(d));
		scanf("%lld%lld%lld", &D, &s1, &s2);
		ll y, sum, dis = 0, ans = 0, e = 1;
		do
		{
			dis++;
			y = D + dis;
			sum = getbinary(y);
			if (sum < s1)
			{
				ll add = s1 - sum;
				cnt = 0;
				while (add)
				{
					if (d[cnt] == 0)
					{
						d[cnt] = 1;
						add--;
					}
					cnt++;
				}
				break;
			}
		} while (sum < s1 || sum > s2);
		for (int i = 0; i < 40; i++)
		{
			if (d[i])
				ans += e;
			e *= 2;
		}
		printf("Case #%lld: ", ++kase);
		printf("%lld\n", ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值