预测新能源发电量
华为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 >stationCapacity,代表总发电量超过电池容量,需要按比例进行缩减。总缩减空间为sum – stationCapacity,统计所有子矩阵可缩减空间和,若为0返回全为0.否则按比例进行缩减,
- sum < minSum说明总发电量低于总下限时,按各子阵的可用放大空间比例分配增加量。总放大空间为minSum – sum.统计总缩减空间为,若小于等于0返回全0.否则按照比例进行方案。
- 不满足上述情况,直接返回基准
c++
#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
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
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
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
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语言
#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;
}