UVA - 10718 Bit Mask(贪心+位运算)

来源:互联网 发布:centos u盘挂载 编辑:程序博客网 时间:2024/05/29 17:43
题目大意:输入3个数 n,l,u,问你能否找出一个数m,在满足 l <= m <= u的情况下。使得m|n最大,如果有多个数都能使得m最大,那么输出最小的那个数。

解析:直接暴力求解肯定tle,所以这题要用贪心+位运算。
从二进制的高位到低位扫描,
(1)如果当前n的二进制位为1,尽量让m该位变为0,但是如果当前二进制位置为1都小于l,则该位置保持1。

(2)如果当前n的二进制位为0,尽量让m该位变为1,前提是要让当前的二进制位为1,小于u,否则该位置为0。

注意:如果移位运算时1要写成1ll,不然会爆表。


#include <cstdio>#include <cstring>#include <cmath>using namespace std;typedef long long ll;int main() {ll n,l,u;while(scanf("%lld%lld%lld",&n,&l,&u) != EOF) {ll min,ans = 0;int len = ceil(log2(u));for(int i = len; i >= 0; i--) {min = ans + (ll)(1ll << i); if((n >> i) & 1) { //如果当前该位置为1,尽量让ans该位置为0if(min <= l) { //但是如果当前位置为1都小于l,则该位置保持1ans = min;}}else { //如果当前位置为0,尽量让ans该位置为1if(min <= u) { //前提是当前位置为1,小于uans = min;}}}printf("%lld\n",ans);}return 0;}


0 0
原创粉丝点击