• Codeforces484 A. Bits


    题目类型:位运算

    传送门:>Here<

    题意:求区间([L,R])内二进制中1的个数最多的那个数,如果有多解输出最小解

    解题思路

    想了15min就一遍A了

    我们可以贪心地在(L)的基础上+1,从小的往大的加。根据二进制的性质,我们不可能把原来的1变成0,除非在更高位搞出一个新的1来。因为如果不在更高位搞出一个1,就肯定比(L)小了。而我们又不可能搞掉一个地位,去弄一个高位,因为这样不仅没有让1的个数增多,反而让数字更大了

    因此我们的最优策略,就是从最低位开始给0的位补1。知道超过(R)为止

    反思

    贪心思想

    Code

    注意,(C++)中的平移运算符(1<<x)是不可以超过31位的(我就是因为这个调试了很久)。所以在(long long)范围下要么手打,要么(1LL<<x)

    /*By DennyQi 2018*/
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int MAXN = 10010;
    const int MAXM = 20010;
    const int INF = 1061109567;
    inline int Max(const int a, const int b){ return (a > b) ? a : b; }
    inline int Min(const int a, const int b){ return (a < b) ? a : b; }
    inline ll read(){
        ll x = 0; int w = 1; register char c = getchar();
        for(; c ^ '-' && (c < '0' || c > '9'); c = getchar());
        if(c == '-') w = -1, c = getchar();
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x<<3) + (x<<1) + c - '0'; return x * w;
    }
    ll N,l,r,ans,num;
    ll power2(ll x){
    	ll res = 1;
    	for(ll i = 1; i <= x; ++i) res *= 2;
    	return res;
    }
    signed main(){
    	N = read();
    	for(ll i = 1; i <= N; ++i){
    		l = read(), r = read();
    		num = 0;
    		for(ll j = 0; j < 61; ++j){
    			if(l & power2(j)){
    				++num;
    			}
    		}
    		ans = l;
    		for(ll j = 0; j < 61; ++j){
    			if((!(l & power2(j))) && (ans + power2(j) <= r)){
    				++num;
    				ans += power2(j);
    			}
    		}
    		printf("%I64d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    sql递归
    Sql Server随机抽取数据效率优化
    sql 左位补齐
    sql语句读取xml
    sql存储过程返回值
    sql 高效随机获取大表数据
    删除临时表
    sql完整事务
    加载静态文件,父模板的继承和扩展
    开始Flask项目
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9744419.html
Copyright © 2020-2023  润新知