预测新能源发电量
华为OD机试新系统真题 华为OD上机考试新系统真题 6月21号 100分题型
华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解
题目内容
某地面光伏电站按区域划分为多个子阵。每个子阵的发电能力有明确的约束:
- 发电能力上限( m a x _ c a p a c i t y max\_capacity max_capacity)
- 发电能力下限( m i n _ c a p a c i t y min\_capacity min_capacity)
- 基准发电量( b a s e _ g e n e r a t i o n base\_generation base_generation)
系统需要根据这些约束,预测整个电站的发电量。预测策略是:
- 每个子阵有一个基准发电量
- 如果总预测发电量超过电站总容量,需要按比例缩减
- 如果总预测发电量低于总容量下限,需要按比例放大
- 最终预测发电量向上取整为整数
调整策略:
- 缩减场景
当总发电量超过电站容量时,按各子阵的可用缩减空间比例分配缩减量
可用缩减空间 = = = b a s e _ g e n e r a t i o n base\_generation base_generation − - − m i n _ c a p a c i t y min\_capacity min_capacity;表示该子阵还能减少多少发电量而不低于下限
缩减量按此比例分配: 缩减 量 i 缩减量_i 缩减量i = 总缩减量 × ( 可用缩减空 间 i 可用缩减空间_i 可用缩减空间i / 总可用缩减空间)
- 放大场景
当总发电量低于总下限时,按各子阵的可用放大空间比例分配增加量
可用放大空间 = m a x _ c a p a c i t y max\_capacity max_capacity - b a s e _ g e n e r a t i o n base\_generation base_generation;表示该子阵还能增加多少发电量而不超过上限
增加量按此比例分配: 增加 量 i 增加量_i 增加量i = 总增加量 × ( 可用放大空 间 i 可用放大空间_i 可用放大空间i / 总可用放大空间)
补充说明
特殊情况处理
- 如果所有子阵都达到下限,但仍超过电站容量:返回全 0 0 0 数组
- 如果所有子阵都达到上限,但仍低于总下限:返回全 0 0 0 数组
要求
最终预测发电量必须满足: m i n _ c a p a c i t y ≤ p r e d i c t e d _ g e n e r a t i o n ≤ m a x _ c a p a c i t y min\_capacity \le predicted\_generation \le max\_capacity min_capacity≤predicted_generation≤max_capacity
- 如果总预测发电量 > > > s t a t i o n _ c a p a c i t y station\_capacity station_capacity,需要按比例缩减
- 如果总预测发电量 < < < 总下限(各子阵 m i n _ c a p a c i t y min\_capacity min_capacity之和),需要按比例放大
- 最终结果必须向上取整为整数(如使用 m a t h . c e i l math.ceil math.ceil)
输入
输入子阵列表数量n
s u b _ a r r a y s sub\_arrays sub_arrays: 子阵列表,每个子阵是一个三元组 m a x _ c a p a c i t y max\\_capacity max_capacity, m i n _ c a p a c i t y min\\_capacity min_capacity, b a s e _ g e n e r a t i o n base\\_generation base_generation,均为整数
s t a t i o n _ c a p a c i t y station\_capacity station_capacity: 电站总容量上限(整数)
输出
返回一维数组,每个元素是对应子阵的预测发电量(向上整数) 如果无法在约束范围内满足总容量要求,返回全 0 0 0 数组
样例1
输入
3
1000 800 900
1200 900 1100
800 600 700
2800
输出
900 1100 700
样例2
输入
3
1000 800 800
1200 900 900
800 600 600
2600
输出
800 900 600
题解
思路:模拟
- 预处理:统计所有子矩阵的
基准和以及最低下限和分别使用sum和minSum进行记录。 - 根据情况进行处理:
- 若
sum >stationCapacity,代表总发电量超过电池容量,需要按比例进行缩减。总缩减空间为sum - stationCapacity,统计所有子矩阵可缩减空间和,若为0返回全为0.否则按比例进行缩减, sum < minSum说明总发电量低于总下限时,按各子阵的可用放大空间比例分配增加量。总放大空间为minSum - sum.统计总缩减空间为,若小于等于0返回全0.否则按照比例进行方案。- 不满足上述情况,直接返回基准
- 若
c++
cpp
#include <algorithm>
#include<bits/stdc++.h>
#include <vector>
using namespace std;
vector<int> predictGenerate(vector<vector<int>>& info, int stationCapacity) {
int n = info.size();
if (n == 0) {
return {};
}
// 基准和 总下线和
long sum = 0, minSum = 0;
for (int i = 0; i < n; i++) {
sum += info[i][2];
minSum += info[i][1];
}
vector<int> ans(n);
for (int i = 0; i < n; i++) {
ans[i] = info[i][2];
}
// 发电量超过电站容量 按比例下调
if (sum > stationCapacity) {
// 缩减空间
long need = sum - stationCapacity;
long availableSum = 0;
for (int i = 0; i < n; i++) {
availableSum += (info[i][2] - info[i][1]);
}
// 没有下调空间,返回全0
if (availableSum <= 0) {
return vector<int>(n, 0);
}
for (int i = 0; i < n; i++) {
int space = info[i][2] - info[i][1];
ans[i] = (int)ceil(ans[i]* 1.0 - need * space / (double) availableSum);
}
// 发电量小于下限和 上调
} else if (minSum > sum) {
long need = minSum - sum;
long availableSum = 0;
for (int i = 0; i < n; i++) {
availableSum += (info[i][0] - info[i][2]);
}
// 没有上调空间,返回全0
if (availableSum <= 0) {
return vector<int>(n, 0);
}
for (int i = 0; i < n; i++) {
int space = info[i][0] - info[i][2];
ans[i] = (int)ceil(ans[i]* 1.0 - need * space / (double) availableSum);
}
}
return ans;
}
int main() {
int n;
cin >> n;
vector<vector<int>> info(n, vector<int>(3));
for (int i = 0; i < n; i++) {
cin >> info[i][0] >> info[i][1] >> info[i][2];
}
int stationCapacity;
cin >>stationCapacity;
vector<int> ans = predictGenerate(info, stationCapacity);
for (int i = 0; i < ans.size(); i++) {
if (i > 0) {
cout << " ";
}
cout << ans[i];
}
return 0;
}
Java
java
import java.util.*;
public class Main {
static List<Integer> predictGenerate(List<List<Integer>> info, int stationCapacity) {
int n = info.size();
if (n == 0) {
return new ArrayList<>();
}
// 基准和 总下线和
long sum = 0;
long minSum = 0;
for (int i = 0; i < n; i++) {
sum += info.get(i).get(2);
minSum += info.get(i).get(1);
}
List<Integer> ans = new ArrayList<>();
for (int i = 0; i < n; i++) {
ans.add(info.get(i).get(2));
}
// 发电量超过电站容量 按比例下调
if (sum > stationCapacity) {
// 缩减空间
long need = sum - stationCapacity;
long availableSum = 0;
for (int i = 0; i < n; i++) {
availableSum += info.get(i).get(2) - info.get(i).get(1);
}
// 没有下调空间,返回全0
if (availableSum <= 0) {
List<Integer> zero = new ArrayList<>();
for (int i = 0; i < n; i++) {
zero.add(0);
}
return zero;
}
for (int i = 0; i < n; i++) {
int space = info.get(i).get(2) - info.get(i).get(1);
ans.set(
i,
(int) Math.ceil(
ans.get(i) - need * space / (double) availableSum
)
);
}
// 发电量小于下限和 上调
} else if (minSum > sum) {
long need = minSum - sum;
long availableSum = 0;
for (int i = 0; i < n; i++) {
availableSum += info.get(i).get(0) - info.get(i).get(2);
}
// 没有上调空间,返回全0
if (availableSum <= 0) {
List<Integer> zero = new ArrayList<>();
for (int i = 0; i < n; i++) {
zero.add(0);
}
return zero;
}
for (int i = 0; i < n; i++) {
int space = info.get(i).get(0) - info.get(i).get(2);
ans.set(
i,
(int) Math.ceil(
ans.get(i) - need * space / (double) availableSum
)
);
}
}
return ans;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
List<List<Integer>> info = new ArrayList<>();
for (int i = 0; i < n; i++) {
List<Integer> row = new ArrayList<>();
row.add(sc.nextInt());
row.add(sc.nextInt());
row.add(sc.nextInt());
info.add(row);
}
int stationCapacity = sc.nextInt();
List<Integer> ans = predictGenerate(info, stationCapacity);
for (int i = 0; i < ans.size(); i++) {
if (i > 0) {
System.out.print(" ");
}
System.out.print(ans.get(i));
}
}
}
Python
python
import math
def predict_generate(info, station_capacity):
n = len(info)
if n == 0:
return []
# 基准和 总下线和
total = 0
min_sum = 0
for row in info:
total += row[2]
min_sum += row[1]
ans = [row[2] for row in info]
# 发电量超过电站容量 按比例下调
if total > station_capacity:
# 缩减空间
need = total - station_capacity
available_sum = 0
for row in info:
available_sum += row[2] - row[1]
# 没有下调空间,返回全0
if available_sum <= 0:
return [0] * n
for i in range(n):
space = info[i][2] - info[i][1]
ans[i] = math.ceil(
ans[i] - need * space / available_sum
)
# 发电量小于下限和 上调
elif min_sum > total:
need = min_sum - total
available_sum = 0
for row in info:
available_sum += row[0] - row[2]
# 没有上调空间,返回全0
if available_sum <= 0:
return [0] * n
for i in range(n):
space = info[i][0] - info[i][2]
ans[i] = math.ceil(
ans[i] - need * space / available_sum
)
return ans
n = int(input())
info = [list(map(int, input().split())) for _ in range(n)]
station_capacity = int(input())
ans = predict_generate(info, station_capacity)
print(*ans)
JavaScript
js
const readline = require("readline");
function predictGenerate(info, stationCapacity) {
const n = info.length;
if (n === 0) {
return [];
}
// 基准和 总下线和
let sum = 0;
let minSum = 0;
for (let i = 0; i < n; i++) {
sum += info[i][2];
minSum += info[i][1];
}
const ans = info.map(row => row[2]);
// 发电量超过电站容量 按比例下调
if (sum > stationCapacity) {
// 缩减空间
const need = sum - stationCapacity;
let availableSum = 0;
for (let i = 0; i < n; i++) {
availableSum += info[i][2] - info[i][1];
}
// 没有下调空间,返回全0
if (availableSum <= 0) {
return Array(n).fill(0);
}
for (let i = 0; i < n; i++) {
const space = info[i][2] - info[i][1];
ans[i] = Math.ceil(
ans[i] - need * space / availableSum
);
}
// 发电量小于下限和 上调
} else if (minSum > sum) {
const need = minSum - sum;
let availableSum = 0;
for (let i = 0; i < n; i++) {
availableSum += info[i][0] - info[i][2];
}
// 没有上调空间,返回全0
if (availableSum <= 0) {
return Array(n).fill(0);
}
for (let i = 0; i < n; i++) {
const space = info[i][0] - info[i][2];
ans[i] = Math.ceil(
ans[i] - need * space / availableSum
);
}
}
return ans;
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const lines = [];
rl.on("line", line => {
lines.push(line);
});
rl.on("close", () => {
let idx = 0;
const n = parseInt(lines[idx++]);
const info = [];
for (let i = 0; i < n; i++) {
info.push(lines[idx++].trim().split(/\s+/).map(Number));
}
const stationCapacity = parseInt(lines[idx++]);
const ans = predictGenerate(info, stationCapacity);
console.log(ans.join(" "));
});
Go
go
package main
import (
"fmt"
"math"
)
func predictGenerate(info [][]int, stationCapacity int) []int {
n := len(info)
if n == 0 {
return []int{}
}
// 基准和 总下线和
var sum int64 = 0
var minSum int64 = 0
for i := 0; i < n; i++ {
sum += int64(info[i][2])
minSum += int64(info[i][1])
}
ans := make([]int, n)
for i := 0; i < n; i++ {
ans[i] = info[i][2]
}
// 发电量超过电站容量 按比例下调
if sum > int64(stationCapacity) {
// 缩减空间
need := sum - int64(stationCapacity)
var availableSum int64 = 0
for i := 0; i < n; i++ {
availableSum += int64(info[i][2] - info[i][1])
}
// 没有下调空间,返回全0
if availableSum <= 0 {
return make([]int, n)
}
for i := 0; i < n; i++ {
space := info[i][2] - info[i][1]
ans[i] = int(math.Ceil(
float64(ans[i]) -
float64(need)*float64(space)/float64(availableSum),
))
}
// 发电量小于下限和 上调
} else if minSum > sum {
need := minSum - sum
var availableSum int64 = 0
for i := 0; i < n; i++ {
availableSum += int64(info[i][0] - info[i][2])
}
// 没有上调空间,返回全0
if availableSum <= 0 {
return make([]int, n)
}
for i := 0; i < n; i++ {
space := info[i][0] - info[i][2]
ans[i] = int(math.Ceil(
float64(ans[i]) -
float64(need)*float64(space)/float64(availableSum),
))
}
}
return ans
}
func main() {
var n int
fmt.Scan(&n)
info := make([][]int, n)
for i := 0; i < n; i++ {
info[i] = make([]int, 3)
fmt.Scan(&info[i][0], &info[i][1], &info[i][2])
}
var stationCapacity int
fmt.Scan(&stationCapacity)
ans := predictGenerate(info, stationCapacity)
for i := 0; i < len(ans); i++ {
if i > 0 {
fmt.Print(" ")
}
fmt.Print(ans[i])
}
}
C语言
cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int* predictGenerate(int info[][3], int n, int stationCapacity) {
if (n == 0) {
return NULL;
}
// 基准和 总下线和
long long sum = 0;
long long minSum = 0;
for (int i = 0; i < n; i++) {
sum += info[i][2];
minSum += info[i][1];
}
int* ans = (int*)malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) {
ans[i] = info[i][2];
}
// 发电量超过电站容量 按比例下调
if (sum > stationCapacity) {
// 缩减空间
long long need = sum - stationCapacity;
long long availableSum = 0;
for (int i = 0; i < n; i++) {
availableSum += info[i][2] - info[i][1];
}
// 没有下调空间,返回全0
if (availableSum <= 0) {
for (int i = 0; i < n; i++) {
ans[i] = 0;
}
return ans;
}
for (int i = 0; i < n; i++) {
int space = info[i][2] - info[i][1];
ans[i] = (int)ceil(
ans[i] -
need * space / (double)availableSum
);
}
// 发电量小于下限和 上调
} else if (minSum > sum) {
long long need = minSum - sum;
long long availableSum = 0;
for (int i = 0; i < n; i++) {
availableSum += info[i][0] - info[i][2];
}
// 没有上调空间,返回全0
if (availableSum <= 0) {
for (int i = 0; i < n; i++) {
ans[i] = 0;
}
return ans;
}
for (int i = 0; i < n; i++) {
int space = info[i][0] - info[i][2];
ans[i] = (int)ceil(
ans[i] -
need * space / (double)availableSum
);
}
}
return ans;
}
int main() {
int n;
scanf("%d", &n);
int info[n][3];
for (int i = 0; i < n; i++) {
scanf("%d%d%d",
&info[i][0],
&info[i][1],
&info[i][2]);
}
int stationCapacity;
scanf("%d", &stationCapacity);
int* ans = predictGenerate(info, n, stationCapacity);
for (int i = 0; i < n; i++) {
if (i > 0) {
printf(" ");
}
printf("%d", ans[i]);
}
free(ans);
return 0;
}