#P3244. 光伏场地建设规划(200分)
-
1000ms
Tried: 44
Accepted: 24
Difficulty: 2
所属公司 :
华为od
光伏场地建设规划(200分)
题面描述
在祖国西北部的某地区,电力公司希望建设光伏电站以生产清洁能源,该地区的长为 L、宽为 W,每平方公里的年发电量已经调查清楚。公司计划选择一个边长为 S 的正方形区域,要求其总发电量不低于最低标准 T。输入数据包括区域的长、宽、正方形边长及最低发电量要求,随后是每平方公里的发电量数值,输出则是符合条件的正方形区域数量。
思路
经典二维前缀和,遍历所有的边长为S的子矩阵查一遍即可。
关键代码分析
1.prefix[i][j] = grid[i-1][j-1] + prefix[i-1][j] + prefix[i][j-1] - prefix[i-1][j-1]
这句代码用于计算二维前缀和数组 prefix[i][j] 的值,表示从原始矩阵 grid 的左上角到位置 (i-1,j-1) 的所有元素之和。具体来说,prefix[i][j] 包含当前元素 grid[i-1][j-1] 的值,加上上方区域的总和 prefix[i-1][j] 和左侧区域的总和 prefix[i][j-1],再减去重叠部分 prefix[i-1][j-1]
2.long long total = prefix[i+S][j+S] -prefix[i][j+S] - prefix[i+S][j] + prefix[i][j]
这句代码用于计算指定 SxS 矩形区域的总发电量,具体来说,它利用了之前构建的二维前缀和数组 prefix。prefix[i+S][j+S] 表示从原始矩阵的左上角 (0,0) 到矩形右下角 (i+S-1,j+S-1) 的总和。接下来,减去 prefix[i][j+S] 和 prefix[i+S][j],这两个值分别代表了矩形上方和左侧的区域和,从而避免了重复计算的部分。最后,加上 prefix[i][j],这是为了纠正因上方和左侧的区域和中减去的重叠部分。因此,这一行代码能有效计算出从 (i,j) 到 (i+S-1,j+S-1) 的矩形区域总和
cpp
#include <iostream>
#include <vector>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int L, W, S;
long long T;
cin >> L >> W >> S >> T;
// 使用长整型以防止发电量过大
vector<vector<long long>> grid(L, vector<long long>(W, 0));
for(int i=0;i<L;i++){
for(int j=0;j<W;j++){
cin >> grid[i][j];
}
}
// 计算前缀和
vector<vector<long long>> prefix(L+1, vector<long long>(W+1, 0));
for(int i=1;i<=L;i++){
for(int j=1;j<=W;j++){
prefix[i][j] = grid[i-1][j-1] + prefix[i-1][j] + prefix[i][j-1] - prefix[i-1][j-1];
}
}
int count = 0;
// 遍历所有可能的 SxS 矩形区域
for(int i=0;i + S <= L;i++){
for(int j=0;j + S <= W;j++){
// 计算区域总发电量
long long total = prefix[i+S][j+S] - prefix[i][j+S] - prefix[i+S][j] + prefix[i][j];
if(total >= T){
count++;
}
}
}
cout << count;
}
python
def main():
import sys
input = sys.stdin.read
data = input().splitlines()
# 读取 L, W, S, T
L, W, S, T = map(int, data[0].split())
# 使用长整型以防止发电量过大
grid = []
for i in range(1, L + 1):
grid.append(list(map(int, data[i].split())))
# 计算前缀和
prefix = [[0] * (W + 1) for _ in range(L + 1)]
for i in range(1, L + 1):
for j in range(1, W + 1):
prefix[i][j] = (grid[i - 1][j - 1] +
prefix[i - 1][j] +
prefix[i][j - 1] -
prefix[i - 1][j - 1])
count = 0
# 遍历所有可能的 SxS 矩形区域
for i in range(L - S + 1):
for j in range(W - S + 1):
# 计算区域总发电量
total = (prefix[i + S][j + S] -
prefix[i][j + S] -
prefix[i + S][j] +
prefix[i][j])
if total >= T:
count += 1
print(count)
if __name__ == "__main__":
main()
java
import java.util.Scanner;
public class SolarPower {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取 L, W, S, T
int L = scanner.nextInt();
int W = scanner.nextInt();
int S = scanner.nextInt();
long T = scanner.nextLong();
// 使用长整型以防止发电量过大
long[][] grid = new long[L][W];
for (int i = 0; i < L; i++) {
for (int j = 0; j < W; j++) {
grid[i][j] = scanner.nextLong();
}
}
// 计算前缀和
long[][] prefix = new long[L + 1][W + 1];
for (int i = 1; i <= L; i++) {
for (int j = 1; j <= W; j++) {
prefix[i][j] = grid[i - 1][j - 1]
+ prefix[i - 1][j]
+ prefix[i][j - 1]
- prefix[i - 1][j - 1];
}
}
int count = 0;
// 遍历所有可能的 SxS 矩形区域
for (int i = 0; i + S <= L; i++) {
for (int j = 0; j + S <= W; j++) {
// 计算区域总发电量
long total = prefix[i + S][j + S]
- prefix[i][j + S]
- prefix[i + S][j]
+ prefix[i][j];
if (total >= T) {
count++;
}
}
}
System.out.println(count);
scanner.close();
}
}
题目内容
祖国西北部有一片大片荒地,其中零星的分布着一些湖泊,保护区,矿区;
整体上常年光照良好,但是也有一些地区光照不太好。
某电力公司希望在这里建设多个光伏电站,生产清洁能源对每平方公里的土地进行了发电评估,其中不能建设的区域发电量为 0 kw,可以发电的区域根据光照,地形等给出了每平方公里年发电量 x 千瓦。
我们希望能够找到其中集中的矩形区域建设电站,能够获得良好的收益。
输入描述
第一行输入为调研的地区长L,宽W,以及准备建设的电站【长宽相等,为正方形】的边长S,最低要求的发电量T。
之后每行为调研区域每平方公里的发电量。
例如,输入为:
2 5 2 6 1 3 4 5 8 2 3 6 7 1
表示调研的区域大小为长 2 宽 5 的矩形,我们要建设的电站的边长为 2,建设电站最低发电量为 6
0<L,W<=1000,S<=min(L,W),0<T<=1000
输出描述
输出为这样的区域有多少个?
上述输入长度为 2 的正方形满足发电量大于等于 6 的区域有 4 个。
则输出为:
4
样例1
输入
2 5 2 6
1 3 4 5 8
2 3 6 7 1
输出
4
说明
输入长为2,宽为5的场地,建设的场地为正方形场地,边长为2,要求场地的发电量大于等于6
样例2
输入
2 5 1 6
1 3 4 5 8
2 3 6 7 1
输出
3
说明
输入长为2,宽为5的场地,建设的场地为正方形场地,边长为1,要求场地的发电量大于等于6
样例3
输入
2 5 1 0
1 3 4 5 8
2 3 6 7 1
输出
10
说明
输入长为2,宽为5的场地,建设的场地为正方形场地,边长为1,要求场地的发电量大于等于0