二进制差异数(C++ ) 刷题记录

题库目录

2023华为OD备考【转载】

题目描述

对于任意两个正整数A和B,定义它们之间的

差异值和相似值

**差异值:**A、B转换成二进制后,对于二进制的每一位,对应位置的bit值不相同则为1,否则为0;

**相似值:**A、B转换成二进制后,对于二进制的每一位,对应位置的bit值都为1则为1,否则为0;

现在有n个正整数A0到A(n-1),问有多少(i, j) (0<=i<j<n),Ai和Aj的差异值大于相似值。

假设A=5,B=3;则A的二进制表示101;B的二进制表示011;

则A与B的差异值二进制为110;相似值二进制为001;

A与B的差异值十进制等于6,相似值十进制等于1,满足条件。

输入描述

一个n接下来n个正整数

数据范围:1<=n<=10^5,1<=A[i]<2^30

输出描述

满足差异值大于相似值的对数

用例

<table><tbody><tr><td>输入</td><td>4<br>4 3 5 2</td></tr><tr><td>输出</td><td>4</td></tr><tr><td>说明</td><td>满足条件的分别是(0,1)(0,3)(1,2)(2,3),共4对。</td></tr></tbody></table>

题目解析

题目描述中,

A,B差异值其实就是A和B二进制的按位异或运算,即A ^ B。

A,B相似值其实就是A和B二进制的按位与运算,即A & B。

本题主要是找规律:

本题的规律其实很容易发现,那就是看A,B的最高位1是否处于相同位,如果相同,比如

A:1010

B:1100

那么差异值就是0110,相似值就是1000,可以发现,A,B最高位的1,在按位异或运算下被换成0,在按位与的运算下,变成了1,因此这种情况下,相似值必然大于差异值,不符合要求。

如果A,B的最高位1不处于相同位,比如

A:1010

B:0110

那么差异值就是1100,相似值就是0010,可以发现,A,B的最高位不同,因此按位异或运算下被换成了1,而按位与运算下变成了0,因此这种情况下,差异值必然大于相似值,符合要求。

总结:

差异值的最高位为1,相似值的最高位为0。因此我们只要找到最高位的1的种类,然后相互组合即可。

C++

#include<iostream> //头文件,用于输入输出
#include<vector> //头文件,用于使用vector容器
#include<algorithm> //头文件,用于使用算法函数
#include<bitset> //头文件,用于使用二进制位操作

using namespace std; //命名空间

vector<int> split(string str) { //定义函数split,将字符串转换为整数vector
    vector<int> nums; //初始化整数vector
    while (str.find(" ") != string::npos) { //当字符串中还有空格时
        int found = str.find(" "); //找到空格的位置
        nums.push_back(stoi(str.substr(0, found))); //将空格前的字符串转换为整数并加入vector
        str = str.substr(found + 1); //将字符串更新为去除空格的后半部分
    }    
    nums.push_back(stoi(str)); //将最后一部分字符串转换为整数并加入vector
    return nums; //返回整数vector
}

int main() //主函数
{
    string param_str; //定义字符串param_str,用于存储输入的第一行字符串
    getline(cin, param_str); //读取一行字符串
    int n = stoi(param_str); //将字符串转换为整数
 
    string op_str; //定义字符串op_str,用于存储输入的第二行字符串
    getline(cin, op_str); //读取一行字符串
    vector<int> nums = split(op_str); //将字符串转换为整数vector
 
    vector<int> bit_info(100, 0);  //定义长度为100的整数vector,初始化为0
    
    for (auto num : nums) { //遍历整数vector
      bitset<32> num_binary(num); //将整数转换为32位二进制数
      string num_binary_str= num_binary.to_string(); //将二进制数转换为字符串
      num_binary_str.erase(0,num_binary_str.find_first_not_of("0")); //去除字符串前面的0
      int len = num_binary_str.size(); //计算字符串长度
    
      if ("" == num_binary_str) { //如果字符串为空
        bit_info[0]++; //将bit_info[0]加1
      } else { //否则
        bit_info[num_binary_str.size()]++; //将bit_info[字符串长度]加1
      }
    }
    
    int res = 0; //定义整数res,初始化为0
    for (int i = 0; i < bit_info.size(); i++) { //遍历bit_info
      for (int j = i + 1; j < bit_info.size(); j++) { //遍历bit_info
        res += bit_info[i] * bit_info[j]; //计算res的值
      }
    }
    cout<< res; //输出res的值
    return 0; //程序结束
}

#23届找工作求助阵地#
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-09 12:02
ssob上原来真有BOSS啊
硫蛋蛋:这种也是打工的,只不是是给写字楼房东打工
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务