牛客编程巅峰赛S1第3场 - 青铜&白银
发布日期:2021-05-14 23:49:13 浏览次数:22 分类:精选文章

本文共 3503 字,大约阅读时间需要 11 分钟。

位数求和与牛客网问题解析

问题一:位数求和

目标:找出所有长度为n的数中,各个位上的数字之和为m的这些数的总和。

思路分析

  • 范围限定:长度为n的数可以表示为[10^{n-1}, 10^n)。遍历这个范围内的数。
  • 位数求和:编写一个函数sum1(A),将给定的数A的每一位数字相加,得到结果。
  • 暴力解法:逐个检查区间内的数,计算符合条件的数,累加所有符合条件的数值。

代码实现

// 计算各位数字之和long long sum1(long long A) {    long long sum = 0;    while (A != 0) {        sum += A % 10;        A /= 10;    }    return sum;}// 主函数:求满足条件的所有数的和long long sum(int n, int m) {    long long start = pow(10, n-1);    long long end = pow(10, n);    long long result = 0;        for (long long num = start; num < end; num++) {        if (sum1(num) == m) {            result += num;        }    }    return result;}

问题二:牛客网问题POJ3104

问题描述

有n件带水的衣服,存储在数组a中。定义两种烘干方式:

  • 自然烘干:每分钟减少1滴水。
  • 烘干机:每分钟减少k滴水,且一次只能放一件衣服。
  • 目标:找出最短时间,使所有衣物烘干完毕。

    思路分析

    • 特殊情况处理:当k=1时,烘干机无法提升效率,应直接选择最大的水量进行计算。
    • 优化思路:使用二分法确定最短时间,通过排序找到水量最大的衣物,从而优化计算范围。
    • 时间计算:在每次二分查找中,检查给定时间x是否能满足所有衣物烘干的需求。若无法满足,则需要更长时间;反之,可能存在优化空间。

    代码实现

    // 判断时间是否足够bool check(ll x, int n, vector
    a, int k) { ll sum = 0; for (int i = 0; i < n; i++) { if (a[i] > x) { sum += static_cast
    (ceil((a[i] - x) / (k - 1))); } } return (sum <= x) ? 1 : 0;}int solve(int n, vector
    a, int k) { // 特殊情况处理:k=1 if (k == 1) { return static_cast
    (a.back()); } // 确定排序后的最大值区间 sort(a.begin(), a.end()); ll left = 1; ll right = a[n-1]; ll ans = 0; while (left <= right) { ll mid = (left + right) / 2; if (check(mid, n, a, k)) { ans = mid; right = mid - 1; } else { left = mid + 1; } } return ans;}

    创新点总结

    • 二分法优化:避免暴力遍历,显著缩短计算时间。
    • 排序优化:找出最大水量衣物,减少没必要的计算。
    • 数学模型优化:通过公式计算每件衣物所需烘干机使用次数,提升算法效率。

    将以上两篇技术文档转化为自然流畅的中文描述:

    代码解析与问题解决

    位数求和问题

    目标:计算所有长度为n且各位数字和为m的数的总和。

    解决思路

  • 范围限定:生成长度为n的所有数,范围为[10^{n-1}, 10^{n})。
  • 求和函数:编写函数sum1(A),逐位相加得到数字和。
  • 遍历检查:遍历每个数,检查其位数和是否等于m,并将符合条件的数累加。
  • 代码实现

    public class Solution {    public static long long sum1(long long A) {        long long sum = 0;        while (A != 0) {            sum += A % 10;            A /= 10;        }        return sum;    }    public static long long sum(int n, int m) {        long long start = (long) Math.pow(10, n - 1);        long long end = (long) Math.pow(10, n);        long long result = 0;        for (long long num = start; num < end; num++) {            if (sum1(num) == m) {                result += num;            }        }        return result;    }}

    牛客网问题POJ3104解析

    问题描述

    n件衣物,每件带有不同水量。定义如下两种烘干方式:

    • 自然烘干:每分钟减少1滴水。
    • 烘干机:每分钟减少k滴水,且只能烘干一个衣物。

    目标:求最短时间烘干所有衣物。

    思路优化

  • 特殊情况处理:k=1时,效率不变,直接取最大水量衣物处理时间。
  • 二分法算法:利用二分查找确定最少时间。每次取中间值,通过check函数判断时间是否足够。
  • 排序优化:最大水量衣物决定最长时间,先对其进行处理,再处理其他衣物。
  • 代码实现

    #include 
    #include
    #include
    using namespace std;bool check(long long x, int n, vector
    a, int k) { long long sum = 0; for (int i = 0; i < n; i++) { if (a[i] > x) { sum += static_cast
    (ceil((a[i] - x) / (k - 1))); } } return sum <= x;}int solve(int n, vector
    a, int k) { if (k == 1) { return a.back(); } sort(a.begin(), a.end()); long long left = 1; long long right = a.back(); long long ans = 0; while (left <= right) { long long mid = (left + right) / 2; if (check(mid, n, a, k)) { ans = mid; right = mid - 1; } else { left = mid + 1; } } return static_cast
    (ans);}

    优化效果

    • 二分法减少时间复杂度:从O(N)优化至O(log(max - min))。
    • 排序优化:通过找到最大值,将后续计算范围缩窄,提升效率。
    • 数学判定:通过数学公式优化检查准确性,避免不必要的重复计算。

    以上就是针对这两个问题的详细解析与代码实现。

    上一篇:牛客编程巅峰赛S1第4场-青铜&白银
    下一篇:Leetcode 面试经典01.05 一次编辑 & 01.06 字符串压缩(C/C++)

    发表评论

    最新留言

    表示我来过!
    [***.240.166.169]2025年04月30日 19时34分13秒