二进制差异数(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届找工作求助阵地#