UVA 10714 Bit Mask

来源:互联网 发布:2015年十大网络用语 编辑:程序博客网 时间:2024/05/21 05:40

题目要求:,给出三个32位数字,N,L,U(L<=U),找到一个数字M(L<=M<=U),使得N|M的结果最大,并且M最小

贪心的方式来处理,首先设法找到最大值,把每个数字转换成数组来进行处理,对于N,高位到低位,如果数组位数为0,那么尝试将M的对应位数设置为1,如果设置为1之后。

不大于上界U,那么这个方式合理,继续查找。另外需要注意的是如果N对应位数为0将M对应位置设置为1后,需要将设置为1的后面的所有都置0判断是否大于上界。

这句话可能不太好理解,参考数据 5,7,8.答案输出应该是8,在转换过程中存在0111,进行转换,如果直接转换成1111,那么肯定大于U,需要转换为1000进行一下判断,

所有才有代码中的temp和intcpy。

另外捉急位运算只知道规则。还是不太会用。这里全部用数组来模拟,捉急。。需要学习一下大牛的代码,虽然AC了。。

#include <map>#include <set>#include <list>#include <cmath>#include<cctype>#include <ctime>#include <deque>#include <stack>#include <queue>#include <cstdio>#include <string>#include <vector>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define LL long long#define PI 3.1415926535897932626using namespace std;int gcd(int a, int b){return a % b == 0 ? b : gcd(b, a % b);}//  int change[32];int ans;long N,L,U;int len;int res[32];int temp[32];int bit;//转换N之后的数字位数inline long long power(int n){    long long ans=1;    for (int i=1;i<=n;i++)        ans*=2;        return ans;}inline void tran_arr()//将数字N转换进入数字{     bit=0;int tmp[32];len=0;     memset(tmp,0,sizeof(tmp));    while (N>1)    {        tmp[bit++]=N%2;        N/=2;    }    tmp[bit++]=N%2;//这里要更改以32位为基础,将这些数字平移到尾侧    for (int i=bit-1,j=32-bit;i>=0;i--,j++)        change[j]=tmp[i];    /*for (int i=0;i<32;i++) printf("%d",change[i]);    putchar('\n');*/    while (L>1)    {        tmp[len++]=L%2;        L/=2;    }    tmp[len++]=L%2;    for (int i=len-1,j=32-len;i>=0;i--,j++)        res[j]=tmp[i];    /*for (int i=0;i<32;i++) printf("%d",res[i]);    putchar('\n');*/}inline long long tran_int(){    long long  sum=0;    for (int i=0;i<32;i++)       if (res[i])        sum+=power(31-i);        //printf("%lld\n",sum);        return sum;}inline void intcpy(int *temp,int *res){    for (int i=0;i<32;i++)        temp[i]=res[i];}void slove(){    tran_arr();//刚开始的res就是最小值注意,下面的程序中只能使他变大    int cas=0;    for (int i=0;i<32;i++)    {        if (change[i]==0)        {             if (res[cas]==0)             {                 intcpy(temp,res);                 res[cas]=1;//复制到temp                 for (int k=i+1;k<32;k++)res[k]=0;                 if (tran_int()>U)intcpy(res,temp);//如果不超过届那么不用更改             }        }        cas++;    }    printf("%lld\n",tran_int());}int main(){    while (scanf("%lld%lld%lld",&N,&L,&U)==3)    {        //M的下界是L,上届是U        memset(res,0,sizeof(res));        memset(change,0,sizeof(change));        slove();    }    return 0;}


0 0
原创粉丝点击