学生穿校服问题|豆包MarsCode AI 刷题

115 阅读3分钟

问题描述:

在字节学校,有 n 个学生,他们相信自己是学校里最靓的仔,并希望自己的衣服与周围人的不同。学校的规定是,所有学生只能穿黑色或白色校服(0表示白色,1表示黑色)。学生们的座位是围成一个圈的,每天如果有一个学生发现自己左右邻居的衣服与自己一样,那么他就会在第二天换上另一种颜色的校服。如果两边的衣服与他不一样,他则继续穿原来的衣服。

问题要求:

  • 计算学生们的衣服在第几天会稳定下来。稳定指的是在某一天,第二天的衣服与当天相同。
  • 稳定下来后,计算“时尚达人”的数量。时尚达人定义为穿着与相邻同学都不一样的学生。

如果学生们永远不会稳定下来,则输出 -1 -1

解题思路:

  1. 状态更新规则

    • 每个学生根据左右邻居的穿着决定是否更换衣服:如果左右两侧学生的衣服与自己相同,则第二天更换衣服;否则继续穿原来的衣服。
    • 由于学生是围成圈的,所以首尾学生也是相邻的。
  2. 稳定条件

    • 如果某天的穿着与前一天相同,则说明穿着稳定下来。
    • 如果天数超过 n 仍然没有稳定,则说明无法稳定,返回 -1 -1
  3. 时尚达人判定

    • 稳定下来后,统计每个学生的左右邻居,若左右邻居穿着不同于自己,则该学生为时尚达人。

解题步骤:

  1. 模拟每一天的衣服变化,直到状态稳定。
  2. 统计总的稳定天数,并计算稳定后的时尚达人数量。
  3. 如果天数过多,返回 -1 -1 表示无法稳定。

代码实现:

#include <iostream> 
#include <vector>
#include <string> 
std::vector<int> solution(int n, const std::string &data) 
{ std::string current = data; std::string next = current; int days = 0; // 模拟每一天的变化 
while (true) { 
// 更新每个学生的穿着 next = current;
for (int i = 0; i < n; ++i) { 
int left = (i == 0) ? current[n - 1] : current[i - 1];
// 左邻 int right = (i == n - 1) ? current[0] : current[i + 1];
// 右邻 
if (left == current[i] && right == current[i]) { 
next[i] = (current[i] == '0') ? '1' : '0'; // 更换衣服
} 
} // 如果今天的穿着与昨天相同,说明稳定了 if (next == current) { break; } // 更新穿着 current = next; days++;
// 防止无限循环(如果天数太大) 
if (days > n) { return {-1, -1}; } }
// 计算时尚达人数量 
int fashionistaCount = 0;

for (int i = 0; i < n; ++i) { 
int left = (i == 0) ? current[n - 1] : current[i - 1]; // 左邻 int right = (i == n - 1) ? current[0] : current[i + 1]; 
// 右邻 
if (current[i] != left && current[i] != right) 
{ fashionistaCount++; } } 
return {days, fashionistaCount};
} 
int main() {
// 测试用例 std::cout << (solution(4, "0000") == std::vector<int>{-1, -1}) << std::endl; std::cout << (solution(4, "1110") == std::vector<int>{2, 4}) << std::endl; return 0; 
}

ai代码分析:

  1. 模拟过程

    • 使用 current 字符串表示当前状态,next 字符串表示下一天的状态。
    • 每天根据左右邻居的穿着判断是否要更换衣服,并更新 next
    • 如果 currentnext 相同,表示穿着稳定,退出循环。
  2. 稳定性判断

    • 若经过 n 天还没有稳定,认为无法稳定,返回 -1 -1
  3. 时尚达人统计

    • 在稳定后遍历学生,如果其左右邻居与自己穿着不同,则该学生是时尚达人。

时间复杂度:

  • 每天最多更新一次状态,更新过程是线性的,即 O(n)
  • 最多进行 n 轮更新,因此时间复杂度为 O(n^2),但是实际过程中状态变化较快,通常不会达到 n 轮。

空间复杂度:

  • 使用了 O(n) 的额外空间来存储当前和下一天的状态。

总结:

这道题通过模拟学生衣服变化的过程来解决问题,关键在于正确判断每个学生的左右邻居,并实现状态的更新。虽然最坏情况下时间复杂度为 O(n^2),但实际情况通常较为高效。