小程序:或与加

23 篇文章 0 订阅
15 篇文章 1 订阅

题目描述:

给定 x,k,求满足 x + y = x | y 的第 K 小的正整数 y。 | 是二进制的或(or)运算。例如,3 | 5 = 7.
比如当 x = 5, k = 1时,返回2,因为 5+1 = 6 不等于 5 | 1 = 5,而 5+2 = 7 等于 5 | 2 = 7

输入描述: 每组测试用例仅包含一组数据,每组数据为两个正整数 x , k。满足 0 < x, k <= 2,000,000,000

输出描述:
输出一个数y


分析

关于此题的或与加,仔细看题可以发现,x,k的值很大,不能进行一一对比,需要用位运算的方式,直接计算。例如: 5 + 2 = 5 | 2
即 1001 + 0010 = 1001 | 0010
仔细观察可以发现,符合 x&y = 0,条件的,也符合x + y = x | y。
统计一下 x 中的 0 的位置(yi),然后用int count_comp( int *cur, int count, long int k )
中的计算方法进行计算,求得第K个符合要求的数

代码

/**

 * @filename     Or_Add.cc

 * @Synopsis     output the data y  which in accordance with  x+y = x|y 

 * @author       XIU

 * @version      1

 * @date         2016-05-05

 */



#include<iostream>

#include<bitset>

#include<string>

#include<math.h>

#include<cstdlib>

using namespace std;





/* ============================================================================*/

/**

 * @Synopsis      

 *

 * @Param         cur       a array which stores the location of zero in the inputdata

 * @Param         count     the number of the zeros

 * @Param         k

 *

 * @Returns       the result data(y)

 */

/* ============================================================================*/

int count_comp( int *cur, int count, long int k )

{



    int data = 0;

    bitset<1000> t = k;



    for(int i=0; i<count; i++ )

    {

        data = data + t[i]*pow( 2,cur[i] );

    }



    return data;

}



/* ============================================================================*/

/**

 * @Synopsis      

 *

 * @Param         x

 * @Param         k

 *

 * @Returns       the result data(y)

 */

/* ============================================================================*/

int compute( long int x, long int k )

{

    int count = 0;



    bitset<10000> t;

    t = x;

    //cout<< endl<<t[0] << t[1] <<t[2]<< endl;

    int yi[10000];

    for(long int y =0 ; y<=10000 ; y++)

    {



        if( t[y]==0 )

        {

            yi[count] = y;

            count++;

            if( k < pow(2,count) )

            {



                int data = 0;



                data = count_comp( yi, count ,k );



                return data;

            }

        }



    }



}



int main()

{



    long int x,k;

    int count = 1;

    int *data = (int *)malloc(sizeof(int)*count);

    while( cin>>x>>k )

    {

        if(count > 1) 

        {

            data = (int *)realloc( data,sizeof(int)*( count ) );

        }

        data[count-1] = compute(x,k) ;

        count++;

    }



//  cout<<"------------------------"<<endl;

    for(int i=0; i<count-1; i++ )

    {

        cout << data[i] <<endl;

    }



    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值