统计能源使用时段(C++/Go/C/Js/Java/Py)题解
华为OD机试新系统真题 华为OD上机考试新系统真题 7月22号 100分题型
华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解
题目内容
某智慧园区管理系统记录了
N
N
N 个连续的能源使用时段,每个时段使用的能源类型用整数表示(1=太阳能,2=风能,3=电能,4=天然气,5=地热能)。 为了优化能源配置,管理员需要分析:在这
N
N
N 个时段中,连续使用不超过
2
2
2 种能源的最长时段长度是多少? 请编写程序计算这个最大长度。
输入描述
- 输入是一个整数数组,表示各时段的能源类型
- 数组元素:1=太阳能,2=风能,3=电能,4=天然气,5=地热能
- 约束条件:
1
⩽
1 \\leqslant
1⩽ 数组长度⩽
100000
\\leqslant 100000
⩽100000,能源类型为1
1
1–5
5
5 的整数
输出描述
输出最长连续时段的长度。
补充说明:
如果输入为空,则输出
0
0
0
样例1
输入
1,2,1,2,3,2,2,2
输出
5
说明
- 最长满足条件的连续时段是 [2 3 2 2 2](下标
3
3
3 到7
7
7),长度5
5
5 - 该时段只使用了
2
2
2 种能源(2
2
2 和3
3
3)
样例2
输入
1,2,3,4,5
输出
2
说明 最长的满足条件的连续时段是
2
2
2,因为每个时段都不一样。
题解
思路:双指针
- 更新count[type[right]]++, 如果更新之后,count[type[right]] == 1说明区域内种类增加更新differCount += 1
- 如果differCount > 2时,迭代右移left直到differCount == 2结束,处理逻辑如下
- 更新count[type[left]]–, 如果更新之后,count[type[left]] == 0说明区域内种类减少更新differCount -= 1
- 并移动left++
- 尝试更新maxLen, 通过比较maxLen和right – left +1的值
C++
#include<bits/stdc++.h>
#include <cctype>
#include <vector>
using namespace std;
// 通用 切割函数 函数 将字符串str根据delimiter进行切割
vector<int> split(const string& str, const string& delimiter) {
vector<int> result;
size_t start = 0;
size_t end = str.find(delimiter);
while (end != string::npos) {
result.push_back(stoi(str.substr(start, end – start)));
start = end + delimiter.length();
end = str.find(delimiter, start);
}
// 添加最后一个部分
result.push_back(stoi(str.substr(start)));
return result;
}
int getMaxLen(vector<int>& type) {
vector<int> count(6, 0);
int maxLen = 0;
int left = 0;
int differCount = 0;
int n = type.size();
for (int right = 0; right < n; right++) {
count[type[right]]++;
// 种类增加
if (count[type[right]] == 1) {
differCount++;
}
// 保证指针区域不同种类长度不超过2
while (differCount > 2) {
count[type[left]]—;
if (count[type[left]] == 0) {
differCount -= 1;
}
left++;
}
maxLen = max(maxLen, right – left + 1);
}
return maxLen;
}
int main() {
string input;
getline(cin, input);
vector<int> type = split(input, ",");
cout << getMaxLen(type);
return 0;
}
Java
import java.util.*;
public class Main {
static int getMaxLen(int[] type) {
int[] count = new int[6];
int maxLen = 0;
int left = 0;
int differCount = 0;
int n = type.length;
for (int right = 0; right < n; right++) {
count[type[right]]++;
// 种类增加
if (count[type[right]] == 1) {
differCount++;
}
// 保证指针区域不同种类长度不超过2
while (differCount > 2) {
count[type[left]]—;
if (count[type[left]] == 0) {
differCount—;
}
left++;
}
maxLen = Math.max(maxLen, right – left + 1);
}
return maxLen;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
String[] arr = input.split(",");
int[] type = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
type[i] = Integer.parseInt(arr[i]);
}
System.out.println(getMaxLen(type));
}
}
Python
def getMaxLen(type):
count = [0] * 6
maxLen = 0
left = 0
differCount = 0
n = len(type)
for right in range(n):
count[type[right]] += 1
# 种类增加
if count[type[right]] == 1:
differCount += 1
# 保证指针区域不同种类长度不超过2
while differCount > 2:
count[type[left]] -= 1
if count[type[left]] == 0:
differCount -= 1
left += 1
maxLen = max(maxLen, right – left + 1)
return maxLen
input_str = input().strip()
type = list(map(int, input_str.split(",")))
print(getMaxLen(type))
JavaScript
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function getMaxLen(type) {
const count = new Array(6).fill(0);
let maxLen = 0;
let left = 0;
let differCount = 0;
const n = type.length;
for (let right = 0; right < n; right++) {
count[type[right]]++;
// 种类增加
if (count[type[right]] === 1) {
differCount++;
}
// 保证指针区域不同种类长度不超过2
while (differCount > 2) {
count[type[left]]—;
if (count[type[left]] === 0) {
differCount—;
}
left++;
}
maxLen = Math.max(maxLen, right – left + 1);
}
return maxLen;
}
rl.on("line", function (line) {
const type = line.split(",").map(Number);
console.log(getMaxLen(type));
});
Go
package main
import (
"fmt"
"strconv"
"strings"
)
func getMaxLen(t []int) int {
count := make([]int, 6)
maxLen := 0
left := 0
differCount := 0
n := len(t)
for right := 0; right < n; right++ {
count[t[right]]++
// 种类增加
if count[t[right]] == 1 {
differCount++
}
// 保证指针区域不同种类长度不超过2
for differCount > 2 {
count[t[left]]—
if count[t[left]] == 0 {
differCount—
}
left++
}
if right–left+1 > maxLen {
maxLen = right – left + 1
}
}
return maxLen
}
func main() {
var input string
fmt.Scanln(&input)
parts := strings.Split(input, ",")
typeArr := make([]int, len(parts))
for i, s := range parts {
typeArr[i], _ = strconv.Atoi(s)
}
fmt.Println(getMaxLen(typeArr))
}
C语言
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 100005
// 通用 切割函数 函数 将字符串str根据delimiter进行切割
int split(char *str, const char *delimiter, int nums[]) {
int cnt = 0;
char *token = strtok(str, delimiter);
while (token != NULL) {
nums[cnt++] = atoi(token);
token = strtok(NULL, delimiter);
}
return cnt;
}
int max(int a, int b) {
return a > b ? a : b;
}
int getMaxLen(int type[], int n) {
int count[6] = {0};
int maxLen = 0;
int left = 0;
int differCount = 0;
for (int right = 0; right < n; right++) {
count[type[right]]++;
// 种类增加
if (count[type[right]] == 1) {
differCount++;
}
// 保证指针区域不同种类长度不超过2
while (differCount > 2) {
count[type[left]]—;
if (count[type[left]] == 0) {
differCount—;
}
left++;
}
maxLen = max(maxLen, right – left + 1);
}
return maxLen;
}
int main() {
char input[1000000];
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\\n")] = '\\0';
int type[MAXN];
int n = split(input, ",", type);
printf("%d\\n", getMaxLen(type, n));
return 0;
}

