hdu 5491 The Next (位运算)

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

题目大意:给定一个数D,它的二进制数中1的个数为L,求比D大的数的最小值x且x的二进制数中1的个数num满足s1 <= num <= s2

分析:将D+1变成n,求其二进制数中1的个数L

 

(1)如果L在(s1, s2)范围内,直接输出

(2)如果num<s1,从右到左找0的最小位i,将该位的0改成1(即:1的个数少了,增加一个1),n的值则增加2^i(即:n += 2^i)

 (3) 如果num>s2,从右到左找1的最小位i,将该位+1(即:1的个数多了,需要减少1),n的值则增加2^i(即: n += 2^i)

 从左到右找是为了保证n值最小增加

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<algorithm>

const int N = 110;
typedef long long ll;

using namespace std;

int d[N];

int get(ll n)
{
    int j = 0, num = 0;
    while(n)
    {
        d[j++] = n % 2;
        if(n % 2 == 1)
            num++;
        n /= 2;
    }
    return num;
}//求n的二进制中1的个数

ll Pow(int a, int b)
{
    ll ans = 1;
    while(b)
    {
        if(b % 2 == 1)
            ans *= a;
        a *= a;
        b /= 2;
    }
    return ans;
}//快数幂求a的b次幂

int main()
{
    int t, num, a, b, x = 0;
    ll n;
    scanf("%d", &t);
    while(t--)
    {
        x++;
        scanf("%I64d%d%d", &n, &a, &b);
        memset(d, 0, sizeof(d));
        n++;
        num = get(n);
        printf("Case #%d: ", x);
        while(1)
        {
            if(num >= a && num <= b)
            {
                printf("%I64d\n", n);
                break;
            }
            else if(num < a)
            {
                int k = 0;
                while(d[k])
                    k++;
                d[k] = 1;
                n += Pow(2, k);
                num++;
            }
            else if(num > b)
            {
                int k = 0;
                while(!d[k])
                    k++;
                n += Pow(2, k);
                num = get(n);
            }
        }
    }
    return 0;
}
时间: 2024-08-02 11:04:34

hdu 5491 The Next (位运算)的相关文章

HDU 5491 The Next(位运算)

题意:已知D(0<=D<2^31).s1.s2,其中L为D转化为二进制数时1的个数,题目保证s1<=L<=s2,求一个数,满足以下条件: 1.比D大 2.转化为二进制时1的个数在[s1, s2]内 3.找出满足1.2条件的最小数字 分析: 1.首先将D加1,假设该数为x,求出x转化为二进制时1的个数cnt. 2.若s1<=cnt<=s2,则输出x 3.若cnt<s1,则应当增加1的数目,因为要保证找到的数字最小,所以要从二进制数的最右边开始改变. 方法:从右向左,

hdu 1882 Strange Billboard(位运算+枚举)

http://acm.hdu.edu.cn/showproblem.php?pid=1882 感觉非常不错的一道题. 给一个n*m(1<=n,m<=16)的矩阵,每一个格子都有黑白两面,当翻一个格子时,它的上下左右都要翻转,问最后使格子全变为白色的最少翻转步数. 仅仅需枚举第一行的状态即可,由于对于第i(i>=2)行j列翻转情况受上一行的制约,仅仅有当上一行也是'X'的时候,该行j列才干翻转,使i-1行j列变为'.',否则i行j列不能翻转.依次进行下去,当最后一行全变为白色,说明翻转成功

HDU 1882 Strange Billboard(位运算)

题目链接 题意 : 给你一个矩阵,有黑有白,翻转一个块可以让上下左右都翻转过来,问最少翻转多少次能让矩阵变为全白. 思路 : 我们从第一行开始枚举要翻转的状态,最多可以枚举到2的16次方,因为你只要第一行的确定了,第二行要翻转的也就确定了,所以第一行的状态决定了最后的状态.看了网上大神,真是让位运算废了啊,,,,,太复杂了...... 1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #

[HDU] 3711 Binary Number [位运算]

Binary Number Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1475    Accepted Submission(s): 933 Problem Description For 2 non-negative integers x and y, f(x, y) is defined as the number of dif

HDU - 6186 前缀和位运算

异或操作蒙蔽了我的双眼 以至于没有第一时间想到前缀和与后缀和 水题做的不够多 #include<bits/stdc++.h> #define rep(i,j,k) for(register int i=j;i<=k;i++) #define rrep(i,j,k) for(register int i=j;i>=k;i--) using namespace std; typedef long long ll; const int maxn = 1e5+11; ll xxor[max

HDU 5023 A Corrupt Mayor&#39;s Performance Art(线段树+优美的位运算)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 Problem Description Corrupt governors always find ways to get dirty money. Paint something, then sell the worthless painting at a high price to someone who wants to bribe him/her on an auction, this

HDU 2276 Kiki &amp; Little Kiki 2 (位运算+矩阵快速幂)

HDU 2276 Kiki & Little Kiki 2 (位运算+矩阵快速幂) ACM 题目地址:HDU 2276 Kiki & Little Kiki 2 题意: 一排灯,开关状态已知,每过一秒:第i个灯会根据刚才左边的那个灯的开关情况变化,如果左边是开的,它就会变化,如果是关的,就保持原来状态.问m秒后的状态. 第1个的左边是最后一个. 分析: 转移不好想啊... 变化是这样的: 原来 左边 变化 1 1 0 1 0 1 0 1 1 0 0 0 然后想到 (~原来)^(左边)=变化

hdu 2721(字符串处理,位运算 暴力)

Persistent Bits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 201    Accepted Submission(s): 116 Problem Description WhatNext Software creates sequence generators that they hope will produce

hdu 3257 Hello World!(位运算 &amp; 模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3257 Hello World! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 476    Accepted Submission(s): 180 Problem Description Your task is to print ...

hdu 5344 (多校联赛) MZL&#39;s xor --- 位运算

here:    首先看一下题吧:题意就是让你把一个序列里所有的(Ai+Aj) 的异或求出来.(1<=i,j<=n) Problem Description MZL loves xor very much.Now he gets an array A.The length of A is n.He wants to know the xor of all (Ai+Aj)(1≤i,j≤n) The xor of an array B is defined as B1 xor B2...xor B