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

【2024华为OD-E卷-100分-木板】(题目+思路+JavaC++Python解析)

题目描述

给定一块木板,其长度为 n 个单位。现在需要在这块木板上切割出 m 个长度为 k 的木板段。每次切割只能沿着木板的整数位置进行,并且每次切割的成本为切割位置到木板两端中较近一端的距离。求最小的切割成本总和。

输入

  • 第一行输入一个整数 n,表示木板的长度。
  • 第二行输入一个整数 m,表示需要切割出的木板段数量。
  • 第三行输入一个整数 k,表示每个木板段的长度。

输出

  • 输出一个整数,表示最小的切割成本总和。

约束条件

  • 1 <= n <= 10^9
  • 1 <= m <= 10^6
  • 1 <= k <= n
  • m * k <= n

思路分析

  1. 贪心算法
    • 我们要尽可能地在靠近木板两端的位置进行切割,这样每次切割的成本会较小。
    • 从木板的一端开始,每次尽量靠近当前未切割部分的中间位置进行切割,可以使得剩余部分的两端都能被有效利用。
    • 但由于木板长度 n 可能非常大,直接模拟每次切割并不现实。我们需要找到一种更有效的方法来计算总成本。
  2. 数学推导
    • 假设木板初始长度为 n,需要切割成 m 段,每段长度为 k。
    • 我们可以发现,切割 m-1 次后,木板会被分成 m 段。
    • 每次切割的成本可以看作是该切割位置到木板两端中较近一端的距离。
    • 我们可以通过数学推导来简化计算,不需要显式地模拟每次切割的位置。
  3. 优化
    • 每次切割可以看作是将木板分成两部分,其中一部分被完全利用(长度为 k),另一部分继续切割。
    • 我们只需要记录每次切割后剩余木板的长度,并计算该次切割的成本(剩余长度的一半,向下取整)。
    • 重复上述过程,直到切割出 m 段木板为止。

Java 编码解析

import java.util.Scanner;

public class WoodBoard {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int k = scanner.nextInt();
        
        scanner.close();
        
        long totalCost = 0;
        int remainingSegments = m - 1;
        int currentLength = n;
        
        while (remainingSegments > 0) {
            // 每次切割的成本是当前长度的一半(向下取整)
            int cutCost = currentLength / 2;
            totalCost += cutCost;
            
            // 切割后剩余长度为剩余长度减去一个k的长度(因为已经切出一个k长度的木板段)
            currentLength -= k;
            
            remainingSegments--;
        }
        
        System.out.println(totalCost);
    }
}

C++ 编码解析

#include <iostream>
using namespace std;

int main() {
    int n, m, k;
    cin >> n >> m >> k;
    
    long long totalCost = 0;
    int remainingSegments = m - 1;
    int currentLength = n;
    
    while (remainingSegments > 0) {
        // 每次切割的成本是当前长度的一半(向下取整)
        int cutCost = currentLength / 2;
        totalCost += cutCost;
        
        // 切割后剩余长度为剩余长度减去一个k的长度(因为已经切出一个k长度的木板段)
        currentLength -= k;
        
        remainingSegments--;
    }
    
    cout << totalCost << endl;
    
    return 0;
}

Python 编码解析

def min_cutting_cost(n, m, k):
    total_cost = 0
    remaining_segments = m - 1
    current_length = n
    
    while remaining_segments > 0:
        # 每次切割的成本是当前长度的一半(向下取整)
        cut_cost = current_length // 2
        total_cost += cut_cost
        
        # 切割后剩余长度为剩余长度减去一个k的长度(因为已经切出一个k长度的木板段)
        current_length -= k
        
        remaining_segments -= 1
    
    return total_cost

# 输入
n = int(input())
m = int(input())
k = int(input())

# 输出
print(min_cutting_cost(n, m, k))


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

相关文章:

  • 无人机方位感知器官磁力传感器!
  • 今日AI和商界事件(2025-02-07)
  • 《手札·开源篇》数字化转型助力永磁电机企业降本增效:快速设计软件如何让研发效率提升40%?
  • 【数据结构】(6) LinkedList 链表
  • 【蓝桥杯—单片机】第十届省赛真题代码题解题笔记 | 省赛 | 真题 | 代码题 | 刷题 | 笔记
  • 蓝桥杯嵌入式备赛(三)—— LED +按键 + LCD
  • fs 文件系统模块
  • 使用PyCharm创建项目以及如何注释代码
  • 【Elasticsearch】指标聚合概述
  • 每日Attention学习22——Inverted Residual RWKV
  • spring-ioc-基础知识
  • leetcode_双指针 557. 反转字符串中的单词 III
  • 上传文件报错:the request was rejected because no multipart boundary was found
  • Linux-查看开放端口
  • java---->策略模式
  • Intellij IDEA如何查看当前文件的类
  • HTML之form表单学习
  • go结构体详解
  • 03-移除元素
  • leetcode:1897. 重新分配字符使所有字符串都相等(python3解法)
  • 开发板适配之UART
  • mybatisPlus介绍
  • Java 21 虚拟线程详解
  • 【C#】一维、二维、三维数组的使用
  • 测试中的第一性原理:回归本质的质量思维革命
  • 数据结构之顺序表和链表