实践出真知,刷题体验 | 豆包MarsCode AI刷题

13 阅读3分钟

实践出真知,刷题体验

当我们要了解说一个东西的效果如何,最简单的方法就是试着用一下。实践出真知这句话到现在都是亘古不变的真理。 下面是官方介绍 豆包 MarsCode 编程助手是豆包旗下的 AI 编程助手,提供以智能代码补全为代表的 AI 功能。它支持主流的编程语言和 IDE,在开发过程中提供单行代码或整个函数的编写建议。此外,它还支持代码解释、单测生成和问题修复等功能,提高了开发效率和质量。

今天我在写一道hard题目的时候,在写完了让豆包给我解答内容。让我们来看看怎么样。 题目是小C的自然连续数乘积。

问题描述

小S在学习素数因子的分解,她希望在[1,n]的范围内,找到一些连续的自然数,这些数的乘积最多包含k个不同的素因子。你的任务是帮助小S找到可以取的连续自然数的最大长度。

连续的自然数指的是不能重复且相邻数的差为1的一组正整数,例如 [2, 3, 4, 5] 和 [5, 6, 7] 都是连续的取数。


测试样例

样例1:

输入:n = 10,k = 3
输出:6

样例2:

输入:n = 20,k = 5
输出:12

样例3:

输入:n = 100,k = 4
输出:10

解题思路

  1. 理解问题

    • 我们需要在[1,n]的范围内找到一组连续的自然数,使得这些数的乘积最多包含k个不同的素因子。
    • 目标是找到这组连续自然数的最大长度。
  2. 数据结构选择

    • 使用unordered_map来记录每个素因子的出现次数。
    • 使用vector来存储每个数的素因子。
  3. 算法步骤

    • 遍历从1到n的所有可能的起始点start
    • 对于每个起始点,使用滑动窗口技术,从start开始向右扩展,直到素因子的数量超过k
    • 在扩展过程中,记录当前窗口的长度,并更新最大长度。
    • 如果当前窗口的素因子数量超过k,则从窗口中移除最左边的数,并更新素因子计数。
  4. 优化

    • 预处理每个数的素因子,避免重复计算。
    • 使用滑动窗口技术减少不必要的计算。

代码实现

#include <iostream>
#include <vector>
#include <unordered_map>
#include <cmath>
using namespace std;
// 判断一个数是否为素数
bool isPrime(int num) {
    if (num <= 1return false;
    for (int i = 2; i <= sqrt(num); ++i) {
        if (num % i == 0return false;
    }
    return true;
}
// 获取一个数的所有素因子
vector<intgetPrimeFactors(int num) {
    vector<int> factors;
    for (int i = 2; i <= num; ++i) {
        if (num % i == 0 && isPrime(i)) {
            factors.push_back(i);
        }
    }
    return factors;
}
int solution(int n, int k) {
    int maxLength = 0;
    for (int start = 1; start <= n; ++start) {
        unordered_map<intint> factorCount;
        int distinctFactors = 0;
        int currentLength = 0;
        for (int end = start; end <= n; 
        ++end) {
            vector<int> factors = 
            getPrimeFactors(end);
            for (int factor : factors) {
                if (factorCount[factor] == 0) 
                {
                    distinctFactors++;
                }
                factorCount[factor]++;
            }
            currentLength++;

            if (distinctFactors > k) {
                break;
            }
            if (distinctFactors <= k) {
               maxLength = max(maxLength, 
                currentLength);
            }
        }
    }

    return maxLength;

}

int main() {
    std::cout << (solution(103) == 6) << 
    std::endl;
    std::cout << (solution(205) == 12) << 
    std::endl;
    std::cout << (solution(1004) == 10) << 
    std::endl;
    return 0;
}

代码解释

  1. isPrime函数

    • 判断一个数是否为素数。
  2. getPrimeFactors函数

    • 获取一个数的所有素因子。
  3. solution函数

    • 使用滑动窗口技术,从每个可能的起始点start开始,向右扩展,直到素因子的数量超过k
    • 记录当前窗口的长度,并更新最大长度。
  4. main函数

    • 测试样例,验证代码的正确性。

总结

通过使用滑动窗口技术和预处理素因子,我们可以在[1,n]的范围内找到一组连续的自然数,使得这些数的乘积最多包含k个不同的素因子,并找到这组连续自然数的最大长度。

感受

可以看得出来还是非常完备的,不过有时候题目的答案无法通过测试,而且比较明显多次出现这个问题,还是需要多个版本进行迭代。