华为OD机考算法题:分积木

2023-09-20 23:45:00

目录

题目部分

解读与分析

代码实现


题目部分

题目分积木
难度
题目说明Solo和koko是两兄弟,妈妈给了他们一大堆积木,每块积木上都有自己的重量。现在他们想要将这些积木分成两堆。哥哥Solo负责分配,弟弟koko要求两个人获得的积木总重量“相等”(根据Koko的逻辑),个数可以不同,不然就会哭,但koko只会先将两个数转成二进制再进行加法,而且总会忘记进位(每个进位都忘记)。如当25(11101)加11(1011)时,koko得到的计算结果是18(10010):
   11001
+ 01011
-------------   
   10010
Solo想要尽可能使自己得到的积木总重量最大,且不让koko哭。
输入描述3
3 5 6
第一行是一个整数N( 2≤ N ≤100 ),表示有多少块积木;第二行为空格分开的N个整数Ci(1 ≤ Ci ≤10^{6}),表示第i块积木的重量。
输出描述11
让koko不哭,输出Solo所能获得积木的最大总重量;否则输出“NO”。
补充说明如果能让koko不哭,输出Solo所能获得的积木的总重量,否则输出-1。
该样例输出为 11 。
解释:Solo 能获得重量为 5 和 6 的两块积木,5 转换成二进制是 101, 6 的二进制是 110,按照 kolo 的计算方法(忘记进位),结果为 3(二进制 011)。kolo 获得重量为 3 的积木,而 solo 获得重量为 11(十进制,5 + 6)的积木。
------------------------------------------------------
示例
示例1
输入3
输出3 5 6
说明11


解读与分析

题目解读

此题要求从一堆数字中,把它们分成 2 份,按照加法不进位的方式,使这两份之和“相等”。在“相等”的前提下,输出实际总和较大的那个数字。
如果任何分法都不能保证“相等”,则输出 -1。

分析与思路

做加法不进位,0 + 0 = 0, 0 + 1 = 1, 1 + 1 = 0。实际上,这就是数字异或(XOR)。

原题中,要求按照异或的方式分成两“等份”,那这两等分异或之后,最终的结果为 0。由于异或的结果与顺序无关,即这一堆数字无论怎么改变顺序,最后异或的结果一定是 0 。既然要求两份中其中一份的数字最大,可以把最小的数字作为一份,其他所有的数字作为一份。最终所有数字之和减去最小的数字,即为输出结果。

如果所有数字的异或结果不为 0,则输出 -1。

那我们的思路就变得很简单了,申明 3 个变量:
1. xorValue,整形数字,初始值为0,记录所有数字的异或值。
2. sum,整形数字,初始值为0,记录所有数字之和。
3. minValue,整形数字,初始值为整形数字的最大值,记录所有数字中的最小值。

遍历所有的数字(设当前正在遍历的数字为 curValue),进行如下操作:
1. 把 xorValue 与 curValue 异或,把结果赋值给 xorValue;
2. 把 curValue 的值加到 sum中;
3. 判断 curValue 与 minValue 的大小,如果 curValue 更小,把它赋值给 minValue。
遍历完所有数字后,如果:
 
·  xorValue 不等于 0 ,输出 -1。
 ·  xorValue 等于 0,输出 ( sum - minValue )。

此题只需要遍历一次数字,使用了 3 个整形变量,时间复杂度为 O(n),空间复杂度为 O(1)。


代码实现

Java代码

import java.util.Scanner;

/**
 * 分积木
 * @since 2023.09.14
 * @version 0.1
 * @author Frank
 *
 */
public class BlockDivision {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			String input = sc.nextLine();
			int count = Integer.parseInt( input );
			input = sc.nextLine();
			String[] numbers = input.split( " " );
			// 此处 count == numbers.count,可以完全不用考虑 count.
			processBlockDivision( numbers );
		}
	}

	private static void processBlockDivision( String numbers[] )
	{
		int xorValue = 0;
		int sum = 0;
		int minValue = Integer.MAX_VALUE;
		for( int i = 0; i < numbers.length; i ++ )
		{
			int curValue = Integer.parseInt( numbers[i] );
			xorValue ^= curValue;
			sum += curValue;
			if( curValue < minValue )
			{
				minValue = curValue;
			}
		}
		if( xorValue != 0 )
		{
			System.out.println( -1 );
		}else
		{
			System.out.println( sum - minValue );
		}
	}
	
}

JavaScript代码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function() {
    while (line = await readline()) {
        // count 可以忽略
        var count = parseInt(line);
        line = await readline();
        var numberArr = line.split(" ");
        processBlockDivision(numberArr);
    }
}();

function processBlockDivision( numbers ) {
    var xorValue = 0;
    var sum = 0;
    var minValue = Number.MAX_VALUE;
    for (var i = 0; i < numbers.length; i++) {
        var curValue = parseInt(numbers[i]);
        xorValue ^= curValue;
        sum += curValue;
        if (curValue < minValue) {
            minValue = curValue;
        }
    }
    if (xorValue != 0) {
        console.log(-1);
    } else {
        console.log(sum - minValue);
    }
}

(完)

更多推荐

STM32H7 Azure RTOS

STM32H7是意法半导体(STMicroelectronics)推出的一款高性能微控制器系列,基于ArmCortex-M7内核。它具有丰富的外设和高性能计算能力,适用于各种应用领域。AzureRTOS(原名ThreadX)是一款实时操作系统(RTOS),是AzureIoT解决方案的一部分。它是一个可裁剪、可扩展的嵌入

算法通关村第十九关:青铜-动态规划是怎么回事

青铜挑战-动态规划是怎么回事动态规划(简称DP,DynamicProgramming):最热门、最重要的算法之一。面试中大量出现,整体偏难。1.热身:重复计算和记忆化搜索(如何说一万次"我爱你")举例:看谁说更多的我爱你classFibonacciTest:def__init__(self):self.count=0d

MOEA算法的背景知识

MOEA算法多目标进化算法优化MOEA工作原理举个例子为什么单一策略可能会导致种群中的个体过于相似?种群在MOEA里面做什么?举例说明多目标进化算法优化MOEAMulti-objectiveevolutionaryalgorithmoptimization(MOEA)多目标进化算法优化(MOEA)是一种用于解决多目标优

日志审计设计-结合spring-aop实现

日志审计设计设计原则和思路:元注解方式结合AOP,灵活记录操作日志能够记录详细错误日志为运营以及审计提供支持日志记录尽可能减少性能影响操作描述参数支持动态获取,其他参数自动记录。1.定义日志记录元注解,根据业务情况,要求description支持动态入参。例:新增应用{applicationName},其中applic

Linux 文件 & 目录管理

Linux文件基本属性Linux系统是一种典型的多用户系统,为了保护系统的安全性,不同的用户拥有不同的地位和权限。Linux系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定。可以使用命令:ll或ls–l来显示一个文件的属性以及文件所属的用户和组,如图所示:详细解析命令:ls-l中显示的内容使用命令:ll

自定义开发成绩查询小程序

在当今数字化时代,教育行业借助技术手段提高教学效果。作为老师,拥有一个自己的成绩查询系统可以帮助你更好地管理学生成绩,并提供更及时的反馈。本文将为你详细介绍如何从零开始搭建一个成绩查询系统,让你的教学工作更加高效和便捷。不过比较便捷好用的方法还是直接使用现成工具。今天我为大家争取到了易查分的福利,只需要在注册时输入邀请

解密Docker容器网络

一个Linux容器能看见的“网络栈”,被隔离在它自己的NetworkNamespace中。1“网络栈”的内容网卡(NetworkInterface)回环设备(LoopbackDevice)路由表(RoutingTable)iptables规则对于一个进程,这些构成它发起、响应网络请求的基本环境。作为一个容器,它可声明直

网络安全(黑客)自学

想自学网络安全(黑客技术)首先你得了解什么是网络安全!什么是黑客网络安全可以基于攻击和防御视角来分类,我们经常听到的“红队”、“渗透测试”等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。无论网络、Web、移动、桌面、云等哪个领域,都有攻与防两面性,例如Web安全技术,既有Web渗透,也有Web

Javascript原型和原型链的详解

🎬岸边的风:个人主页🔥个人专栏:《VUE》《javaScript》⛺️生活的理想,就是为了理想的生活!目录原型(Prototype)构造函数和原型对象原型链原型继承1.对象字面量和Object.create():可以使用字面量对象定义属性和方法,并使用Object.create()方法创建一个新对象,并将其原型设置

python特殊函数之__call__函数的作用

作用将一个类实例也可以变成一个可调用对象。详解__call__是Python中一个魔术方法(magicmethod),它用于定义对象的函数调用行为。换句话说,当你尝试调用一个具有__call__方法的对象时,Python会自动调用该方法。下面是一个简单的例子来说明__call__的作用:classMyClass:def

100天精通Python(可视化篇)——第100天:Pyecharts绘制多种炫酷漏斗图参数说明+代码实战

文章目录专栏导读一、漏斗图介绍1.说明2.应用场景二、漏斗图类说明1.导包2.add函数三、漏斗图实战1.基础漏斗图2.标签内漏斗图3.百分比漏斗图4.向上排序漏斗图5.标准漏斗图书籍推荐专栏导读🔥🔥本文已收录于《100天精通Python从入门到就业》:本专栏专门针对零基础和需要进阶提升的同学所准备的一套完整教学,

热文推荐