leetcode1969--数组元素的最小非零乘积

2024-03-20 18:20

本文主要是介绍leetcode1969--数组元素的最小非零乘积,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 题意

给定一个非零的二进制位排列;

允许交换其中两个数的二进制位任意次。

求交换后得到数组的最小非零乘积。

如:

p = 3 a = [ 001 010 011 100 101 110 111 ] p=3\\ a=[001\ 010\ 011\ 100\ 101\ 110\ 111]\\ p=3a=[001 010 011 100 101 110 111]
010101交换位置得到110001
011100交换位置得到110001
得到答案
1x7x1x6x1x6=1512

2. 题解

首先题目中的数组一定是在 [ 1 , 2 p − 1 ] [1,2^{p}-1] [1,2p1]之间;

交换二进制位意味着什么呢?

其实就是将

x + y → x ′ + y ′ x + y = x ′ + y ′ x+y \rightarrow x'+y'\\ x+y=x'+y' x+yx+yx+y=x+y

由于求得的是最小的非0乘积,所以我们最少要保留最低位为1

对于两个数交换后乘积最大实际上是求
m i n ( x y ) , s . t . x + y = k min(xy),s.t. x+y=k min(xy),s.t.x+y=k
所以我们需要尽量将两个数的差值变大。

所以我们分解的形式应为:
a & b = 0 a ⊕ b = 2 p − 1 a\&b=0\\ a \oplus b=2^p-1 a&b=0ab=2p1

所以对于数组 [ 1 , . . . , 2 p − 1 ] [1,...,2^p-1] [1,...,2p1]的乘积为

1 × ( 2 p − 1 ) × ( 2 p − 2 ) 2 p − 1 − 1 1 \times(2^p-1) \times (2^p-2)^{2^{p-1}-1} 1×(2p1)×(2p2)2p11

由于 2 2 p − 1 − 1 2^{2^p-1}-1 22p11很大,所以需要使用快速幂。

  • 代码
class Solution {
public:long long fast_pow(long long a,unsigned long long b) {long long MOD = 1e9+7;long long base = a%MOD;long long ans = 1;while (b) {if (b & 1) ans = ans * base % MOD; b >>= 1;if (b)base = base  * base % MOD;}return ans % MOD ;}int minNonZeroProduct(int p) {long long ans = ((unsigned long long)1 << p) - 1;
int MOD = 1e9+7;long long base = ans - 1;long long  cnt = ((unsigned long long)1 << (p -1)) - 1;// std::cout << "base:" << base << " cnt: " << cnt << std::endl; ans = ans%MOD * fast_pow(base, cnt) %MOD;return ans % MOD;}
};

这篇关于leetcode1969--数组元素的最小非零乘积的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/830353

相关文章

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

poj 1734 (floyd求最小环并打印路径)

题意: 求图中的一个最小环,并打印路径。 解析: ans 保存最小环长度。 一直wa,最后终于找到原因,inf开太大爆掉了。。。 虽然0x3f3f3f3f用memset好用,但是还是有局限性。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#incl