算法竞赛位运算应用

开头先说一道2018河北省省赛的题。

神殿

icebound通过勤工俭学,攒了一小笔钱,于是他决定出国旅游。这天,icebound走进了一个神秘的神殿。神殿由八位守护者守卫,总共由64个门组成,每一道门后都有一个迷宫,迷宫的大小均为100×100。icebound在迷宫中总共耗时T小时,消耗食物K公斤。历经千辛万苦之后,icebound终于穿越了迷宫,到达了神殿的中心。神殿的中心有一个宝箱。宝箱上显示有两个正整数ll和r。icebound苦思冥想,终于发现一些打开宝箱的线索。你需要找到一个数P,它具有一个美妙的性质:它是[l,r]中所有数的二进制表示里,1的个数最多的一个数。如果你发现了这个美妙的数字,你就可以打开宝箱,获得巨额财富。

比如[4,8]中:

4: 0100
5: 0101
6: 0110
7: 0111
8: 1000

二进制表示中1的个数最多的数是7,它含有3个1。

INPUT

  • 输入一行,两个正整数:ll和rr,用空格隔开,代表神殿中宝箱上显示的数。

  • 1<=T<=2^21

  • 1<=K<=10^5

  • 1<=l<r<=2*10^9

OUTPUT

  • 一个十进制数P,代表满足条件的解。如果有多个P满足条件,输出最小的P。

测试样例

4 8

样例输出

7

题意理解:

  • 就是给定一个区间,找区间中二进制一最多的那个数
  • 多个答案取最小值

解题思路:

这道题要是硬做的话,我目前还没有想到比较好的解决方法,搜索?转字符串?排列组合?回溯?好像听上去都可以,但是好像都不太好写,而且复杂度高的不敢想。

但是这道题如果用位运算来做的话,几乎是一道签到提。

n|(n+1)一定会比n的二进制多一个一而且还是从低位向高位加一,保证n以内就可以找到1最多且最小的那个解。

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    long long l,r;
    cin>>l>>r;
    while((l|(l+1))<=r){
        l|=(l+1);
    }
    cout<<l<<endl;
    return 0;
}

这件事告诉我们,签到题就在那里,就看你能不能用签到的方法做了。

对于这道题,我开始也没有想到这个方法,我的确想到二进制是不是在暗示我用位运算做,但是也的确没想到为什么要n|(n+1)看完巨佬的题解才发现,这个方法简直妙啊,于是我决定把这题当作案例记下来,下次好提醒自己遇到意思位运算多想想能不能写一些这样的公式出来。

鉴于我下次可能还是想不到这种巧妙解法(其实我至今不知道这题的解法究竟是凑巧了还是真的有类似这样的板子),我决定多找一些这种题背一背。。。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
头歌C是一款著名的竞赛算法工具,在算法竞赛中有着广泛的应用。第5章介绍了集合Set的应用实例。集合是一种不允许元素重复且没有顺序的数据结构,常用于去重和判重的场合。以下是一些集合应用实例的说明。 首先,集合可以用于判重。在很多情况下,我们需要判断给定的一组数据中是否有重复元素。这时可以利用集合的特性,在将数据依次插入集合过程中,检查每一次插入操作的结果,如果插入失败,则说明数据重复。 其次,集合可以用于求交集和并集。在某些场合下,需要将两个数据集合合并或者求交集。集合提供了相应的操作方法,能够方便地进行这些运算。例如,给定两个集合A和B,可以使用集合的“交集”操作,得到A和B中共有的元素组成的新集合。 此外,集合还可以用于去重。在实际应用中,有时会遇到需要对一组数据进行去重操作的问题。利用集合特性,可以将数据依次插入集合,由于集合不允许元素重复,最终得到的集合就是原始数据的去重结果。 最后,集合可以用于判断元素是否存在。在某些场景中,需要判断某个给定元素是否存在于一个集合中。利用集合提供的查询方法,可以快速地判断元素是否存在于集合中。 综上所述,头歌C的算法竞赛第5章集合Set的应用实例主要涉及到判重、求交集与并集、去重以及判断元素存在等操作。通过灵活应用集合相关的方法,可以提高算法竞赛的解题效率,并简化解题的复杂度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值