您的位置:首页 > 其它

UVa 10718 - Bit Mask

2012-08-09 20:40 369 查看
贪心,M在保证与N做OR运算的结果最大的基础上,使M的值最小。

可以先将上界和下界都转化为二进制,先确定M的最高位,M的最高位可以从u的最高位开始试(理由很简单),再依次确定之后的数字,每个数字尽量保证与N的二进制相应位置的数字互补(如果N的二进制的某一位是 1,则M的相应位尽量为0,这样才也能保证总值最大,M值尽量小),但也要[b]保证在每一位贪心的过程不能使M值超过[N,M]的范围。[/b]

代码如下:

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>

using namespace std;

void D_bite(char *str, unsigned long long num) // 将数字化成二进制
{
if(!num)
str[0] = '0';
else
for(int i = 0; num; i++)
{
str[i] = num % 2 + '0';
num /= 2;
}
}
unsigned long long B_dight(char *str, int len) // 将二进制化成数字
{
unsigned long long num = 0;
for(int i = 0; i < len; i++)
if(str[i] == '1')
num += (1LL << i);
return num;
}
int main()
{
#ifdef test
freopen("in.txt", "r", stdin);
#endif
unsigned long long l, u, n;
char U[65], M[65], L[65], N[65];
while(scanf("%llu%llu%llu", &n, &l, &u) != EOF)
{
memset(U, 0, sizeof(U));
memset(N, 0, sizeof(N));
memset(M, 0, sizeof(M));
memset(L, 0, sizeof(L));
D_bite(U, u);
D_bite(L, l);
D_bite(N, n);
int len_u = strlen(U), len_m = len_u, len_l = strlen(L);
M[len_m - 1] = '1';
if(!u)  // 当上界为0时,需要特殊处理
M[len_m - 1] = '0';
while(1)
{
if(N[len_m - 1] == '1' && len_m > len_l)
{
--len_m;
M[len_m] = '\0';
M[len_m - 1] = '1';
}
else
break;
}
int ffct = len_m - 1;
for(int i = 0; i < len_m - 1; i++)
M[i] = '0';
while(ffct >= 0)
{
if(N[ffct] != '1')
{
M[ffct] = '1';
if(B_dight(M, len_m) > u) // 相应位置赋为‘1’时,考虑是否超上界
M[ffct] = '0';
}
else
{
M[ffct] = '0';
if(B_dight(M, len_m) < l) // 相应位置赋为‘0’时,考虑是否超下界
{
memset(M, '1', sizeof(M[0]) * ffct);
if(B_dight(M, len_m) < l)
M[ffct] = '1';
memset(M, '0', sizeof(M[0]) * ffct);
}

}
--ffct;
}
printf("%llu\n", B_dight(M, len_m));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: