豆包MarsCode AI刷题|最大乘积区间问题、时尚圈的衣着稳定性问题

88 阅读6分钟

 一、最大乘积区间问题

问题描述

小R手上有一个长度为 n 的数组 (n > 0),数组中的元素分别来自集合 [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]。小R想从这个数组中选取一段连续的区间,得到可能的最大乘积。

你需要帮助小R找到最大乘积的区间,并输出这个区间的起始位置 x 和结束位置 y (x ≤ y)。如果存在多个区间乘积相同的情况,优先选择 x 更小的区间;如果 x 相同,选择 y 更小的区间。

注意:数组的起始位置为 1,结束位置为 n


测试样例

样例1:

输入:n = 5, arr = [1, 2, 4, 0, 8]
输出:[1, 3]

样例2:

输入:n = 7, arr = [1, 2, 4, 8, 0, 256, 0]
输出:[6, 6]

样例3:

输入:n = 8, arr = [1, 2, 4, 8, 0, 256, 512, 0]
输出:[6, 7]

解题思路: 

问题理解

我们需要从一个数组中找到一段连续的区间,使得这段区间的乘积最大。数组中的元素只包含 [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] 这些值。

关键点

  1. 乘积的计算:由于数组中的元素都是2的幂次,乘积的计算相对简单,但需要注意乘积可能会非常大,因此需要考虑溢出问题。
  2. 0的处理:0乘以任何数都为0,因此如果区间中包含0,那么这个区间的乘积就是0。
  3. 区间的选择:如果存在多个区间乘积相同的情况,优先选择 x 更小的区间;如果 x 相同,选择 y 更小的区间。

数据结构与算法

  1. 遍历数组:我们可以通过遍历数组来计算每个可能的区间的乘积。
  2. 动态规划:可以使用动态规划的思想来记录当前区间的乘积,并根据当前元素是否为0来决定是否重置区间。
  3. 记录最大乘积:在遍历过程中,记录最大乘积及其对应的区间。

最终代码:

def solution(n, data):
    max_product = 0
    best_start = -1
    best_end = -1
    
    # 遍历数组,尝试所有可能的区间
    for start in range(n):
        current_product = 1
        for end in range(start, n):
            # 计算当前区间的乘积
            current_product *= data[end]
            
            # 如果乘积为0,跳过这个区间
            if current_product == 0:
                break
            
            # 如果当前乘积大于最大乘积,更新最大乘积和区间
            if current_product > max_product:
                max_product = current_product
                best_start = start
                best_end = end
            # 如果乘积相等,选择更小的区间
            elif current_product == max_product:
                if start < best_start or (start == best_start and end < best_end):
                    best_start = start
                    best_end = end
    
    # 返回区间的起始和结束位置
    return [best_start + 1, best_end + 1]

if __name__ == "__main__":
    # Add your test cases here
    print(solution(5, [1, 2, 4, 0, 8]) == [1, 3])
    print(solution(7, [1, 2, 4, 8, 0, 256, 0]) == [6, 6])

运行结果:

 二、时尚圈的衣着稳定性问题

问题描述

小U在时尚圈组织了一场“校服日”活动,有 n 名学生围成一圈参加活动。每位学生都穿着白色或黑色的校服,白色用 0 表示,黑色用 1 表示。每一天,如果某个学生发现自己和相邻的两位学生穿着相同颜色的校服,那么他会在第二天更换成另一种颜色的校服;否则,他会保持不变。

你的任务是帮助小U判断,在第几天学生们的穿着会达到稳定状态——即某一天后,所有学生的穿着不再发生任何变化。同时,你还需要计算在稳定后,有多少学生的校服颜色与其相邻的同学不同,这些学生被称为“时尚达人”。

最终你需要返回一个包含两个元素的数组:

  • 第一个数字表示稳定下来的天数。如果永远无法稳定,则输出 -1
  • 第二个数字表示稳定后成为“时尚达人”的学生人数。如果永远无法稳定,则输出 -1

测试样例

样例1:

输入:n = 4 ,data = "0000"
输出:[-1, -1]

样例2:

输入:n = 4 ,data = "1110"
输出:[2, 4]

样例3:

输入:n = 6 ,data = "010101"
输出:[1, 6]

解题思路:

问题理解

  1. 学生座位排列:学生围成一个圈,这意味着第1个学生和第n个学生是相邻的。
  2. 校服颜色变化规则:如果一个学生发现相邻的两个学生穿的衣服都跟他一样,则他会在第二天换成另一个颜色的校服,否则保持不变。
  3. 稳定状态:当某一天所有学生的校服颜色都不再变化时,系统达到稳定状态。
  4. 时尚达人:稳定后,与相邻同学穿不同校服的学生被称为“时尚达人”。

数据结构选择

  • 字符串:用于表示每一天学生的校服颜色。
  • 循环队列:由于学生围成一个圈,可以使用循环队列来处理相邻关系。

算法步骤

  1. 初始化:读取输入的n和初始校服颜色字符串。

  2. 模拟每一天的变化

    • 创建一个新的字符串来存储下一天的校服颜色。
    • 遍历每个学生,检查其相邻的两个学生是否穿相同颜色的校服。
    • 根据规则更新新字符串。
  3. 检查稳定状态

    • 如果某一天的校服颜色与前一天相同,则达到稳定状态。
    • 记录稳定的天数。
  4. 计算时尚达人

    • 在稳定状态下,统计与相邻同学穿不同校服的学生数量。

 最终代码:

#include <iostream>
#include <vector>
#include <string>

std::vector<int> solution(int n, const std::string &data) {
    std::vector<int> result = {-1, -1};
    std::string tmp = data;
    int changes = 0;
    int days = 0;

    // 初始检查
    for (int i = 0; i < n; i++) {
        if (i == 0) {
            if (tmp[0] == tmp[n - 1] && tmp[0] == tmp[1]) {
                changes++;
            }
        } else if (i == n - 1) {
            if (tmp[n - 1] == tmp[n - 2] && tmp[n - 1] == tmp[0]) {
                changes++;
            }
        } else {
            if (tmp[i] == tmp[i + 1] && tmp[i] == tmp[i - 1]) {
                changes++;
            }
        }
    }

    if (changes == n) {
        return result;
    }

    days++;

    while (changes != 0) {
        changes = 0;
        std::string k = tmp;

        for (int i = 0; i < n; i++) {
            if (i == 0) {
                if (tmp[0] == tmp[n - 1] && tmp[0] == tmp[1]) {
                    k[0] = (tmp[0] == '0') ? '1' : '0';
                }
            } else if (i == n - 1) {
                if (tmp[n - 1] == tmp[n - 2] && tmp[n - 1] == tmp[0]) {
                    k[n - 1] = (tmp[n - 1] == '0') ? '1' : '0';
                }
            } else {
                if (tmp[i] == tmp[i + 1] && tmp[i] == tmp[i - 1]) {
                    k[i] = (tmp[i] == '0') ? '1' : '0';
                }
            }
        }

        tmp = k;
        days++;

        for (int i = 0; i < n; i++) {
            if (i == 0) {
                if (tmp[0] == tmp[n - 1] && tmp[0] == tmp[1]) {
                    changes++;
                }
            } else if (i == n - 1) {
                if (tmp[n - 1] == tmp[n - 2] && tmp[n - 1] == tmp[0]) {
                    changes++;
                }
            } else {
                if (tmp[i] == tmp[i + 1] && tmp[i] == tmp[i - 1]) {
                    changes++;
                }
            }
        }
    }

    result[1] = 0;
    for (int i = 0; i < n; i++) {
        if (i == 0) {
            if (tmp[0] != tmp[n - 1] && tmp[0] != tmp[1]) {
                result[1]++;
            }
        } else if (i == n - 1) {
            if (tmp[n - 1] != tmp[n - 2] && tmp[n - 1] != tmp[0]) {
                result[1]++;
            }
        } else {
            if (tmp[i] != tmp[i + 1] && tmp[i] != tmp[i - 1]) {
                result[1]++;
            }
        }
    }

    result[0] = days;
    return result;
}

int main() {
    // Add your test cases here
    std::cout << solution(21, "001000001101001101110")[0] << std::endl;
    return 0;
}

运行结果: