华为OD机试真题-预测新能源发电量(C/C++/Py/Java/Js/Go)

预测新能源发电量

华为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)

系统需要根据这些约束,预测整个电站的发电量。预测策略是:

  1. 每个子阵有一个基准发电量
  2. 如果总预测发电量超过电站总容量,需要按比例缩减
  3. 如果总预测发电量低于总容量下限,需要按比例放大
  4. 最终预测发电量向上取整为整数

调整策略:

  • 缩减场景

当总发电量超过电站容量时,按各子阵的可用缩减空间比例分配缩减量

可用缩减空间 = = = 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 / 总可用放大空间)

补充说明

特殊情况处理

  1. 如果所有子阵都达到下限,但仍超过电站容量:返回全 0 0 0 数组
  2. 如果所有子阵都达到上限,但仍低于总下限:返回全 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

  1. 如果总预测发电量 > > > s t a t i o n _ c a p a c i t y station\_capacity station_capacity,需要按比例缩减
  2. 如果总预测发电量 < < < 总下限(各子阵 m i n _ c a p a c i t y min\_capacity min_capacity之和),需要按比例放大
  3. 最终结果必须向上取整为整数(如使用 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

题解

思路:模拟

  1. 预处理:统计所有子矩阵的基准和以及最低下限和分别使用summinSum进行记录。
  2. 根据情况进行处理:
    • 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;
}