全网最全面的华为OD机试真题汇总,100%原题题库,不需要开会员即可查看全部内容,更多考题请查看真题库。
真题库:https://www.yuque.com/codernav.com/od
题目:统计差异值大于相似值二元组个数
知识点:数组进制转换整数范围循环
时间限制:1s 空间限制:256MB 限定语言:不限
题目描述:
对于任意两个正整数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
输出描述:
输出:满足差异值大于相似值的对数
示例1
输入:
4
4 3 5 2
输出:
4
说明:
样例一解释:
满足条件的分别是(0,1) (0,3) (1,2) (2,3),共4对
示例2
输入:
5
3 5 2 8 4
输出:
8
说明:
样例二解释:
满足条件的分别是(0,1) (0,3) (0,4) (1,2) (1,3) (2,3) (2,4) (3,4)
解题思路:
比较需要从右向左进行。
例如:
4和3
4:“100”,3:“11”
差异值:7(111),相似值:0(000)
代码实现一:
package com.codernav.demo.hwod.exam;
import java.util.Arrays;
import java.util.Scanner;
/**
* @title 统计差异值大于相似值二元组个数
* @Description 对于任意两个正整数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,满足条件。
* @Author 开发者导航
* @website https://codernav.com
* @date 2023/5/28
*/
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine();
String[] strings = sc.nextLine().split(" ");
int[] ints = Arrays.stream(strings).mapToInt(Integer::parseInt).toArray();
int res = 0;
for (int i = 0; i < ints.length; i++) {
for (int j = i + 1; j < ints.length; j++) {
if (handle(ints[i], ints[j])) {
res++;
}
}
}
System.out.println(res);
}
public static boolean handle(int A, int B) {
String binaryA = Integer.toBinaryString(A); //十进制转二进制
String binaryB = Integer.toBinaryString(B);
int indexA = binaryA.length() - 1; //二进制字符串长度
int indexB = binaryB.length() - 1;
StringBuilder chayi = new StringBuilder(); //差异值字符串
StringBuilder xiangsi = new StringBuilder(); //相似值字符串
while (indexA >= 0 || indexB >= 0) {
char charA = ' ';
char charB = ' ';
if (indexA >= 0) { //索引大于等于0才有值
charA = binaryA.charAt(indexA); //从尾部开始比较
}
if (indexB >= 0) {
charB = binaryB.charAt(indexB);
}
if (charA == charB) {
chayi.append("0");
} else {
chayi.append("1");
}
if (charA == '1' && charB == '1') {
xiangsi.append("1");
} else {
xiangsi.append("0");
}
indexA--;
indexB--;
}
int intChayi = Integer.valueOf(String.valueOf(chayi.reverse()), 2); //因为是从尾部开始比较,需要反转
int intXiangsi = Integer.valueOf(String.valueOf(xiangsi.reverse()), 2);
return intChayi > intXiangsi;
}
}
代码实现二:Java代码满分实现
package com.codernav.demo.hwod.exam;
import java.util.Scanner;
/**
* @title 统计差异值大于相似值二元组个数
* @Description 对于任意两个正整数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,满足条件。
* @Author 开发者导航
* @website https://codernav.com
* @date 2023/5/28
*/
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] cnt = new int[32];
long ans = 0;
for (int i = 0; i < n; i++) {
int x = sc.nextInt();
int h = 0;
while (x > 0) {
x /= 2;
h++;
}
cnt[h]++;
ans += (i + 1) - cnt[h];
}
System.out.println(ans);
}
}
