首页 > 其他分享 >二进制差异数

二进制差异数

时间:2023-08-05 11:31:48浏览次数:39  
标签:二进制 差异 ++ height int 最高

题目描述

  • 对于任意两个正整数A和B,定义它们之间的差异值和相似值:
  • 差异值: 二进制差异数_数组转换成二进制后,对于二进制的每一位,对应位置的二进制差异数_i++_02值不相同则为1,否则为0
  • 相似值:二进制差异数_数组转换成二进制后,对于二进制的每一位,对应位置的二进制差异数_i++_02值都为1则为1,否则为0
  • 现在有二进制差异数_数组_05个正整数二进制差异数_System_06二进制差异数_i++_07 ,问有多少二进制差异数_数组_08二进制差异数_数组_09的差异值大于相似值
  • 假设
  • 二进制差异数_i++_10的二进制表示二进制差异数_i++_11
  • 二进制差异数_数组_12的二进制表示二进制差异数_数组_13
  • 差异值二进制为二进制差异数_System_14
  • 相似值二进制为二进制差异数_i++_15
  • 二进制差异数_数组_16的差异值十进制等于二进制差异数_i++_17;相似值十进制等于二进制差异数_i++_18;满足条件

输入描述

  • 一个二进制差异数_数组_05接下来二进制差异数_数组_05个正整数
  • 数据范围:二进制差异数_i++_21

输出描述

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

用例

--输入
4
4 3 5 2

--输出
4

--说明
满足条件的分别是 (0, 1) (0, 3) (1, 2) (2, 3) 共4对

题目解析

  • 首先、冷静分析题目中给出的 差异值 和 相似值 的概念
  • 差异值:不相同为 1 ,相同为 0,即 异或 运算规则
  • 相似值:都为 11,否则为 0,即 位与 运算规则
  • 那么现在给到了 个正整数
  • 也就是说 二进制差异数_数组_05 个正整数,可以用一个数组来保存,数据范围 二进制差异数_i++_23,很显然不能双重 for 循环来解决
  • 问有多少的差异值大于相似值
  • 其本质是,在数组中一个元素与其之后位置的元素相对比,判断有多少对元素满足要求。

  • 暴力的解决思路是这样的:对于每一个元素让其和其后面的元素进行 差异值和相似值 的运算处理
  • 时间复杂度 二进制差异数_System_24二进制差异数_数组_25 很容易超时
  • 思考有没有一些特殊性质可以利用
  • 每一个数的取值范围大小是 二进制差异数_i++_26
  • 思考两种情况
  • 如果两个数最高位对应的 bit 位相同
  • 异或的结果则肯定小于位与的结果-因为异或的结果将最高位的 1 消去了
  • 如果两个数最高位对应的 bit 位不同
  • 异或的结果肯定大于位与的结果-因为位与的结果将最高位 1 消去了
  • 那么如何利用这一个性质呢?
  • 那么可以这样考虑-首先可以统计一下所有数字最高位 1 位于二进制数的那一位
  • ex:6 的二进制表示是: 110 ,其最高位的 1 位于二进制数的第 3 位
  • 特别的:0 最高位为 0
  • 由于元素的数据范围是
  • 则可以用一个长度为 31 的数组来统计最高位处于的位置
  • ex:的最高位位于第31位 其二进制表示形式是 100 0000 0000 0000 0000 0000 0000 0000
  • 从右往左,最高位 1 位于第 31 位
  • 那么统计完了之后,如何利用这一性质呢?
  • 那么现在我拥有一个这样的数组 height,该怎么处理呢?
  • 前面已经知道了,两个数最高位对应的 bit 位相同,那么其 差异值 < 相似值,不用考虑
  • 所以只需考虑两个数最高位 bit 位不同的情况
  • so,现在假设 height[0] = 100,height[1] = 50
height[0] = 100 表示 100 个数的最高位 1 的位置在第 0 位
height[1] = 50  表示 50  个数的最高位 1 的位置在第 1 位

那么最高位bit位不相同的配对数一共可以有  50 * 100 = 5000(对)

show code

package com.hw;


import java.util.Scanner;

/**
* desc :   <a href="https://fcqian.blog.csdn.net/article/details/128348806">二进制差异数</a>
* <p>
* create time : 2023/7/26 17:05
*/
public class BinaryDiff {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] A = new int[n];
        for (int i = 0; i < n; i++) {
            A[i] = in.nextInt();
        }

        //binaryDiff(n, A);
        betterWay(n, A);
    }

    // 暴力求解存在超时的问题.
    private static void binaryDiff(int n, int[] A) {
        int ans = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if((A[i] ^ A[j]) > (A[i] & A[j])) {
                    ans++;
                }
            }
        }

        System.out.println(ans);
    }

    private static void betterWay(int n, int[] A) {
        // 数组元素的取值范围是  [1, 2^30]
        // 所以可以用一个长度为 32 的数组,来存储数组元素对应最高位的位置

        int[] height = new int[32];
        // height[31]:在二进制表示中 元素最高位位于第 31 位,从右往左数

        for (int i = 0; i < n; i++) {
            // 对于 2^30 输出 1
            int idx = 32 - Integer.numberOfLeadingZeros(A[i]);
            height[idx]++;
        }

        int ans = 0;

        for (int i = 0; i < height.length; i++) {
            for (int j = i + 1; j < height.length; j++) {
                ans += height[i] * height[j];
            }
        }

        System.out.println(ans);
    }



}

参考

https://fcqian.blog.csdn.net/article/details/128348806

标签:二进制,差异,++,height,int,最高
From: https://blog.51cto.com/u_16079703/6974265

相关文章

  • 二进制-01操作
    Smiling&Weeping----听到一些事,明明不相干的,也会在心中拐好几个弯想到你。 思路:思路就是简单的模拟题,注意一直维护一个len(长度),若是*操作len++;若是/操作我们就需要分两种操作了:若......
  • MySQL中char与varchar的区别:存储机制、性能差异、适用场景
    引用链接:https://www.maoyingdong.com/mysql-char-vs-varchar/ 在MySQL中,varchar和char都可以用来存储字符串。从语义上看,varchar是变长的(Variable-length),char是定长的(Fixed-length)。本文基于MySQL5.7版本,从varchar和char的语义,到存储引擎底层存储机制,探讨它们在存......
  • [算法学习笔记] 多重背包--二进制拆分
    多重背包回顾一下多重背包是什么?有\(n\)种物品,每个物品都有有限个,每个物品都有重量和价值两个参数,你有一个限重为\(W\)的背包,求背包内价值最大。我们朴素的做法是将多重背包拆分成01背包求解,因为每个物品都有有限个,假设第\(i\)个物品有\(j\)个,那么跑\(j\)次01背包即可。但是这......
  • smb和rdp暴破差异分析
     大量smb爆破:   详细日志:-<Eventxmlns="http://schemas.microsoft.com/win/2004/08/events/event">-<System><ProviderName="Microsoft-Windows-Security-Auditing"Guid="{54849625-5478-4994-a5ba-3e3b0328c30d}"/>&......
  • 服务器磁盘IO是什么意思?SATA和固态硬盘的性能差异
    IO实际上是计算机用语,也写作I/O,指输入/输出(Input/Output)。硬盘IO就是指对字节的读取速度,即硬盘的读写能力。今天咱们主要讲一下服务器磁盘IO。服务器硬盘IO的性能也是服务器硬件配置中需要考虑的问题。SATA和固态硬盘的性能差异在哪里呢?首先,硬盘的数据存储在硬盘驱动器内各个扇区......
  • 输出一个数的二进制
    1//输出一个数的二进制2#include<stdio.h>3intmain()4{5intnum;6unsignedmask;7scanf_s("%d",&num);8mask=1u<<31;//定义一个最大位数的二进制数,首位为1,其余为09for(;mask;mask>>=1)//每次1右移一位,直到mask为010......
  • 使用OpenFeign传递二进制流
    在现代的分布式系统中,服务之间的通信变得越来越普遍。OpenFeign是一个流行的JavaHTTP客户端工具,它简化了在微服务架构中进行服务间通信的过程,本文将简单介绍如何使用OpenFeign传递二进制流。什么是OpenFeign?OpenFeign是一个用于声明式、模板化的HTTP客户端的Java库。它简化了编......
  • 智力差异性对课程的影响
    “收藏从未停止,练习从未开始”,或许有那么一些好题好方法,在被你选中收藏后却遗忘在收藏夹里积起了灰?今天请务必打开你沉甸甸的收藏重新回顾,分享一下那些曾让你拍案叫绝的好东西吧!你可以从以下几个方面进行创作(仅供参考)这个在工作之前就做了很多研究,一直觉得不合适发表……重点参考文......
  • centos7 k8s 三节点 全二进制部署 1.23.15
    主机名IP地址Pod网段Service网段master192.168.1.60172.16.0.0/1210.96.0.0/16node01192.168.1.70172.16.0.0/1210.96.0.0/16node02192.168.1.80172.16.0.0/1210.96.0.0/16[root@master~]#cat/etc/redhat-releaseCentOSLinuxrelease7.9.2......
  • 上传图片或文档 二进制文档流方式上传
    问题:接口上传图片需要将图片以二进制得格式与其他字段一块传给后端方案:改变接口传递类型  application/x-www-form-urlencodedletparams={thaliId:this.editData.thaliId,thaliPrice:this.editData.thaliPrice,salesInstructions:thi......