大意:给你一个数字N,L,R,求数字M(L<=M<=R)使得N|M的值最大。
思路:将数字用二进制表示,从高到低枚举32位,采用贪心的思想。
CODE:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
#define MAXN 1001
long long ten2b[MAXN];
long long Mbit[MAXN];
long long tot;
void change( long long n)
{
while(n)
{
ten2b[tot++] = n% 2;
n /= 2;
}
}
long long pow1( int n)
{
long long s = 1;
for( int i = 1; i <= n; i++)
s *= 2;
return s;
}
void init()
{
tot = 0;
memset(ten2b, 0, sizeof(ten2b));
memset(Mbit, 0, sizeof(Mbit));
}
long long Get()
{
long long ans = 0;
for( int i = 0; i <= 31; i++)
{
ans += Mbit[i]*pow1(i);
}
return ans;
}
int main()
{
long long N, L, U;
while(~scanf( " %lld%lld%lld ", &N, &L, &U))
{
init();
change(N);
for( int i = 31; i >= 0; i--)
{
if(!ten2b[i])
{
Mbit[i] = 1;
if(Get() > U) Mbit[i] = 0;
}
else
{
if(Get()+pow1(i) <= L) Mbit[i] = 1;
}
}
long long ans = Get();
printf( " %lld\n ", ans);
}
return 0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
#define MAXN 1001
long long ten2b[MAXN];
long long Mbit[MAXN];
long long tot;
void change( long long n)
{
while(n)
{
ten2b[tot++] = n% 2;
n /= 2;
}
}
long long pow1( int n)
{
long long s = 1;
for( int i = 1; i <= n; i++)
s *= 2;
return s;
}
void init()
{
tot = 0;
memset(ten2b, 0, sizeof(ten2b));
memset(Mbit, 0, sizeof(Mbit));
}
long long Get()
{
long long ans = 0;
for( int i = 0; i <= 31; i++)
{
ans += Mbit[i]*pow1(i);
}
return ans;
}
int main()
{
long long N, L, U;
while(~scanf( " %lld%lld%lld ", &N, &L, &U))
{
init();
change(N);
for( int i = 31; i >= 0; i--)
{
if(!ten2b[i])
{
Mbit[i] = 1;
if(Get() > U) Mbit[i] = 0;
}
else
{
if(Get()+pow1(i) <= L) Mbit[i] = 1;
}
}
long long ans = Get();
printf( " %lld\n ", ans);
}
return 0;
}