当前位置: 首页 > article >正文

【华为OD-E卷 - 分积木 100分(python、java、c++、js、c)】

【华为OD-E卷 - 分积木 100分(python、java、c++、js、c)】

题目

Solo和koko是两兄弟,妈妈给了他们一大堆积木,每块积木上都有自己的重量。
现在他们想要将这些积木分成两堆。
哥哥Solo负责分配,弟弟koko要求两个人获得的积木总重量“相等”(根据Koko的逻辑),个数可以不同,不然就会哭,但koko只会先将两个数转成二进制再进行加法,而且总会忘记进位(每个进位都忘记)。
如当25(11101)加11(01011)时,koko得到的计算结果是18(10010)
11001 +01011
10010 Solo想要尽可能使自己得到的积木总重量最大,且不让koko哭

输入描述

  • 第一行是一个整数N,表示有多少块积木;

2 ≤ N ≤ 100 第二行为空格分开的N个整数Ci,表示第i块积木的重量。

1 ≤ Ci ≤ 10^6

输出描述

  • 如果能让koko不哭,输出Solo所能获得积木的最大总重量;否则输出“NO”

用例

用例一:
输入:
3
3 5 6
输出:
11

python解法

  • 解题思路:
  • 问题描述:

给定一个长度为 n 的整数数组 blocks。
判断是否可以将数组划分为两个或多个子数组,使得这些子数组的 XOR 和为 0。
如果可以,返回数组的总和减去最小值;否则返回 “NO”。
数学基础:

XOR 操作的性质:
a ^ a = 0:任何数字与自身异或结果为 0。
a ^ 0 = a:任何数字与 0 异或结果为数字本身。
XOR 满足交换律和结合律:a ^ b ^ c = c ^ b ^ a。
划分条件:
如果整个数组的 XOR 和 xor_sum 不为 0,则无法划分为 XOR 和为 0 的子数组。
如果 xor_sum = 0,则划分可能存在。具体返回的值与数组的最小值有关。
实现步骤:

计算总和与 XOR 和:
遍历数组,计算数组的总和 total_sum 和 XOR 和 xor_sum。
判断 XOR 和:
如果 xor_sum != 0,返回 “NO”。
如果 xor_sum = 0,说明可以划分,返回 total_sum - min(blocks)。
核心逻辑:
XOR 和为 0 是判断是否能划分的充分条件。
返回 total_sum - min(blocks) 是基于划分后最大化子数组和的策略。
时间复杂度:

总时间复杂度:O(n),遍历数组两次,分别计算总和、XOR 和及最小值。
空间复杂度:O(1),仅使用常量额外空间

def divide_blocks(n, blocks):
    """
    判断是否可以将数组划分为 XOR 和为 0 的子数组。
    如果可以,返回 total_sum - min(blocks),否则返回 "NO"。

    :param n: 数组长度
    :param blocks: 数组
    :return: 可划分时的值或 "NO"
    """
    # 计算数组的总和
    total_sum = sum(blocks)
    # 计算数组的 XOR 和
    xor_sum = 0
    for block in blocks:
        xor_sum ^= block

    # 如果 XOR 和不为 0,无法划分,返回 "NO"
    if xor_sum != 0:
        return "NO"
    
    # 如果 XOR 和为 0,返回 total_sum - 最小值
    return total_sum - min(blocks)


# 读取输入
n = int(input())  # 数组长度
blocks = list(map(int, input().split()))  # 数组元素
# 输出结果
print(divide_blocks(n, blocks))

java解法

  • 解题思路
  • 问题描述:

给定一个整数数组 weightArray,需要判断是否可以将数组划分为多个部分,使得这些部分的 XOR 和为 0。
如果可以,返回数组总和减去最小值;如果不能,返回 “NO”。
关键点分析:

XOR 的性质:
a ^ a = 0:任何数与自身异或结果为 0。
a ^ 0 = a:任何数与 0 异或结果为自身。
XOR 满足交换律和结合律。
划分条件:
如果整个数组的 XOR 和不为 0,无法划分为 XOR 和为 0 的部分。
如果 XOR 和为 0,可以划分为满足条件的部分。
优化策略:

将数组排序,最小值单独处理(通过最小值控制总和)。
总和 correctTotal 初始化为最小值,用于计算数组总和。
XOR 和 xorSum 初始化为最小值,用于计算整个数组的 XOR 值。
实现步骤:

排序数组:
先对数组进行排序,使最小值在数组的第一个位置。
计算总和和 XOR 和:
遍历数组,逐步计算总和 correctTotal 和 XOR 和 xorSum。
判断 XOR 和:
如果 XOR 和为 0,返回 correctTotal - smallest。
如果 XOR 和不为 0,返回 “NO”。
时间复杂度:

数组排序:O(n log n)。
遍历计算总和和 XOR 和:O(n)。
总时间复杂度:O(n log n)。

import java.util.Arrays;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 输入数组大小
        int size = scanner.nextInt();
        int[] weightArray = new int[size];
        // 输入数组元素
        for (int i = 0; i < size; i++) {
            weightArray[i] = scanner.nextInt();
        }
        // 调用结果计算方法并打印结果
        System.out.println(determineResult(size, weightArray));
    }

    /**
     * 判断数组是否可以划分为 XOR 和为 0 的部分
     *
     * @param size 数组大小
     * @param weightArray 输入数组
     * @return 如果可以划分,返回总和减去最小值;否则返回 "NO"
     */
    public static String determineResult(int size, int[] weightArray) {
        // 对数组进行排序
        Arrays.sort(weightArray);

        // 最小值
        int smallest = weightArray[0];
        // 总和初始化为最小值
        int correctTotal = smallest;
        // XOR 和初始化为最小值
        int xorSum = smallest;

        // 遍历剩余的元素,计算总和和 XOR 和
        for (int i = 1; i < size; i++) {
            correctTotal += weightArray[i]; // 累加当前元素
            xorSum ^= weightArray[i];      // 计算 XOR 和
        }

        // 如果 XOR 和为 0,返回总和减去最小值;否则返回 "NO"
        return xorSum == 0 ? String.valueOf(correctTotal - smallest) : "NO";
    }
}

C++解法

  • 解题思路

问题描述:

给定一个整数数组 weights,判断是否可以将其划分为若干子数组,使得这些子数组的 XOR 和为 0。
如果可以,返回总和减去数组中的最小值;如果不可以,返回 “NO”。
解法步骤:

计算 XOR 和:
遍历数组,计算其整体的 XOR 和。
如果 XOR 和不为 0,说明无法划分,直接输出 “NO”。
计算最大总和:
如果 XOR 和为 0,可以划分,将数组的总和减去最小值,作为输出结果。
数学依据:

如果一个数组的 XOR 和为 0,可以通过适当划分,使得子数组的 XOR 和也为 0。
输出总和减去最小值是基于一种贪心思想,假设通过划分后可以最大化剩余部分的和。
算法复杂度:

时间复杂度:
计算 XOR 和:O(n)。
计算总和:O(n)。
找到最小值:O(n)。
总复杂度为 O(n)。
空间复杂度:O(1),只使用常量额外空间。

#include <iostream>
#include <vector>
#include <numeric> // 用于 std::accumulate
#include <algorithm> // 用于 std::min_element

int main() {
    int n;
    std::cin >> n; // 读取数组长度
    std::vector<int> weights(n);

    // 读取数组元素
    for (int &weight : weights) {
        std::cin >> weight;
    }

    // 计算整个数组的 XOR 和
    int xorTotal = 0;
    for (int weight : weights) {
        xorTotal ^= weight;
    }

    // 如果 XOR 和不为 0,无法划分为 XOR 和为 0 的部分
    if (xorTotal != 0) {
        std::cout << "NO" << std::endl;
        return 0;
    }

    // 计算数组总和并减去最小值
    int maxWeight = std::accumulate(weights.begin(), weights.end(), 0) - *std::min_element(weights.begin(), weights.end());
    
    // 输出结果
    std::cout << maxWeight << std::endl;

    return 0;
}

C解法

  • 解题思路

更新中

JS解法

  • 解题思路

更新中

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏


http://www.kler.cn/a/526730.html

相关文章:

  • 集合的奇妙世界:Python集合的经典、避坑与实战
  • 【深度分析】DeepSeek 遭暴力破解,攻击 IP 均来自美国,造成影响有多大?有哪些好的防御措施?
  • 代码随想录|动态规划 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组
  • leetcode——对称二叉树(java)
  • 生成模型:扩散模型(DDPM, DDIM, 条件生成)
  • 17 一个高并发的系统架构如何设计
  • Autogen_core: test_code_executor.py
  • 算法---快速排序
  • Python3 【集合】避坑指南:常见错误解析
  • 【解决方案】MuMu模拟器移植系统进度条卡住98%无法打开
  • 快速提升网站收录:避免常见SEO误区
  • 深入解析JPA实体监听器的使用与实践
  • AI学习指南HuggingFace篇-Hugging Face 的环境搭建
  • 自由学习记录(33)
  • INCOSE需求编写指南-附录 B: 首字母缩略词和缩写
  • 详解python的单例模式
  • DeepSeek-V3技术报告解读
  • Cocos Creator 3.8 2D 游戏开发知识点整理
  • Sqoop支持ORC文件格式
  • AI大模型开发原理篇-4:神经概率语言模型NPLM
  • 【C++题解】1055. 求满足条件的整数个数
  • GWO优化GRNN回归预测matlab
  • 165. 比较版本号
  • 《解码AI大模型涌现能力:从量变到质变的智能跃迁》
  • 如何利用Docker和.NET Core实现环境一致性、简化依赖管理、快速部署与扩展,同时提高资源利用率、确保安全性和生态系统支持
  • Deepseek r1模型对医疗大模型的发展有什么影响?