UVa 10718 - Bit Mask

  题目大意:给一数N,在区间[L, U]上找到一个数M使得M| N的值最大,如果有M有多个可能值,取最小的那个值。

  从最高位开始逐位判断,如果N的该位为0,为使M | N的值最大,M的该位应考虑置为1,然后判断M的该位为1时的可能取值区间[lmin, lmax],如果区间[lmin, lmax]与区间[L, U]有交集,则说明该位可置为1;如果N的该位为1,为使M的值尽可能小,M的该位应考虑置为0,然后判断可能取值区间与[L, U]是否有交集,如果没有交集,该位置为1。

 1 #include <cstdio>
 2 
 3 int main()
 4 {
 5 #ifdef LOCAL
 6     freopen("in", "r", stdin);
 7 #endif
 8     long long d[35];
 9     d[0] = 1;
10     for (int i = 1; i <= 32; i++)
11         d[i] = d[i-1] * 2;
12     long long N, L, U;
13     while (scanf("%lld%lld%lld", &N, &L, &U) != EOF)
14     {
15         int a[32] = {0};
16         for (int i = 0; N > 0; i++)
17         {
18             a[i] = N % 2;
19             N /= 2;
20         }
21         long long lmax, lmin, ans = 0;
22         for (int i = 31; i >= 0; i--)
23         {
24             if (a[i] == 0)
25             {
26                 lmin = ans + d[i];
27                 lmax = ans + d[i+1] - 1;
28                 if (lmin <= U && lmax >= L)
29                     ans += d[i];
30             }
31             else
32             {
33                 lmin = ans;
34                 lmax = ans + d[i] -1;
35                 if (lmax < L || lmin > U)
36                     ans += d[i];
37             }
38         }
39         printf("%lld\n", ans);
40     }
41     return 0;
42 }
View Code

  开始用位移操作,可是总是出现错误,应该是类型范围的问题吧,这方面很弱,感觉这些东西不怎么用,而且有点枯燥,就没怎么看过,即使看也是大概看看,没好好研究,还是要抽时间看一下的(话说,我现在感觉还是用的不多,不过,遇到问题就完蛋了...)

posted @ 2013-08-21 21:35  xiaobaibuhei  阅读(175)  评论(0编辑  收藏  举报