目录
1.题目背景
-
元宵节不放假挺郁闷的,于是时间机智的改到了星期六一整天!
-
题目描述
-
MedalPluS 和他的小伙伴 NOIRP 发掘了一个骨灰级别的游戏——超级弹珠。
-
游戏的内容是:在一个 $n \times n$ 的矩阵里,有若干个敌人,你的弹珠可以摧毁敌人,但只能攻击你所在的行、列里的所有敌人,然后你就可以获得他们的分数之和,现在请你选择一个你的位置,使得能击杀的敌人最多,注意,你不能和敌人在一个地方。
-
输入格式
-
输入有两行,第一行一个正整数 $n$,接下来 $n$ 行,每行 $n$ 列,如果有敌人则为一个正整数,否则为 $0$。
-
输出格式
-
输出共一行,最多分数,如果连你的容身之地都没有,请输出“Bad Game!”
-
样例 #1
-
样例输入 #1
-
4 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1
-
样例输出 #1
-
6
-
提示
-
送分题,客官请拿好,(*^__^*) 嘻嘻……
-
【数据范围】
-
对于 $30 \%$ 的数据,$1 \le n \le 10$。
-
对于 $100 \%$ 的数据,$1 \le n \le 1000$,保证容身之地的数量小于 $10000$。
2.代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 函数 max_score 用于计算能获得的最大分数
int max_score(int n, const vector<vector<int> >& matrix) {
// 初始化行和列的总分数向量,初始值为 0
vector<int> row_sum(n, 0);
vector<int> col_sum(n, 0);
// 用于记录空位置的向量
vector<pair<int, int> > empty_positions;
// 遍历矩阵,计算行和列的总分数,并记录空位置
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
// 如果该位置为空(值为0),记录其坐标
empty_positions.push_back({i, j});
} else {
// 如果该位置有敌人(值不为0),累加到对应的行和列的总分数
row_sum[i] += matrix[i][j];
col_sum[j] += matrix[i][j];
}
}
}
// 如果没有空位置,输出 "Bad Game" 并返回
if (empty_positions.empty()) {
cout << "Bad Game" << endl;
return 0;
}
int max_score = 0;
// 使用传统的迭代器遍历所有空位置
for (vector<pair<int, int>>::const_iterator it = empty_positions.begin(); it != empty_positions.end(); it++) {
// 通过迭代器获取当前空位置的坐标
const pair<int, int>& pos = *it;
int i = pos.first;
int j = pos.second;
// 计算该空位置的总分数(行总分数 + 列总分数)
int score = row_sum[i] + col_sum[j];
// 更新最大分数
max_score = max(max_score, score);
}
// 输出最大分数
cout << max_score << endl;
return 0;
}
int main() {
int n;
// 读取矩阵的大小
cin >> n;
// 初始化 n x n 矩阵,所有元素初始为 0
vector<vector<int>> matrix(n, vector<int>(n));
// 读取矩阵的每个元素
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> matrix[i][j];
}
}
// 调用 max_score 函数,计算并输出结果
max_score(n, matrix);
return 0;
}
-
包含头文件和使用命名空间:
-
#include <iostream>
:包含输入输出流库,用于标准输入输出。 -
#include <vector>
:包含向量库,用于动态数组。 -
using namespace std;
:使用标准命名空间,避免使用std::
前缀。
-
-
max_score 函数:
-
参数:
-
int n
:矩阵的大小。 -
const vector<vector<int>>& matrix
:二维整型向量,表示矩阵。
-
-
局部变量:
-
vector<int> row_sum(n, 0)
:记录每行的敌人总分数。 -
vector<int> col_sum(n, 0)
:记录每列的敌人总分数。 -
vector<pair<int, int>> empty_positions
:记录所有空位置的坐标。
-
-
遍历矩阵:
-
遍历矩阵的每个元素,计算每行和每列的总分数,并记录空位置。
-
-
检查空位置:
-
如果没有空位置,输出 "Bad Game" 并返回。
-
-
计算最大分数:
-
使用迭代器遍历所有空位置,计算每个空位置的分数,并更新最大分数。
-
-
输出结果:
-
输出计算得到的最大分数。
-
-
-
main 函数:
-
读取矩阵大小:
-
从标准输入读取矩阵大小
n
。
-
-
初始化矩阵:
-
初始化
n x n
的矩阵,所有元素初始为 0。
-
-
读取矩阵数据:
-
读取矩阵的每个元素。
-
-
调用 max_score 函数:
-
调用
max_score
函数,计算并输出结果。
-
-
3.注意
新版本写法(使用范围for循环):
#include <iostream>
#include <vector>
using namespace std;
// 函数 max_score 用于计算能获得的最大分数
int max_score(int n, const vector<vector<int>>& matrix) {
vector<int> row_sum(n, 0);
vector<int> col_sum(n, 0);
vector<pair<int, int>> empty_positions;
// 遍历矩阵,计算行和列的总分数,并记录空位置
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
empty_positions.push_back({i, j});
} else {
row_sum[i] += matrix[i][j];
col_sum[j] += matrix[i][j];
}
}
}
// 如果没有空位置,输出 "Bad Game" 并返回
if (empty_positions.empty()) {
cout << "Bad Game" << endl;
return 0;
}
int max_score = 0;
// 使用范围for循环遍历所有空位置
for (const auto& pos : empty_positions) { // 新版本写法
int i = pos.first;
int j = pos.second;
int score = row_sum[i] + col_sum[j];
max_score = max(max_score, score);
}
cout << max_score << endl;
return 0;
}
int main() {
int n;
cin >> n;
vector<vector<int>> matrix(n, vector<int>(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> matrix[i][j];
}
}
max_score(n, matrix);
return 0;
}
旧版本写法(使用迭代器):
#include <iostream>
#include <vector>
using namespace std;
// 函数 max_score 用于计算能获得的最大分数
int max_score(int n, const vector<vector<int>>& matrix) {
vector<int> row_sum(n, 0);
vector<int> col_sum(n, 0);
vector<pair<int, int>> empty_positions;
// 遍历矩阵,计算行和列的总分数,并记录空位置
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
empty_positions.push_back({i, j});
} else {
row_sum[i] += matrix[i][j];
col_sum[j] += matrix[i][j];
}
}
}
// 如果没有空位置,输出 "Bad Game" 并返回
if (empty_positions.empty()) {
cout << "Bad Game" << endl;
return 0;
}
int max_score = 0;
// 使用迭代器遍历所有空位置
for (vector<pair<int, int>>::const_iterator it = empty_positions.begin(); it != empty_positions.end(); ++it) { // 旧版本写法
const pair<int, int>& pos = *it;
int i = pos.first;
int j = pos.second;
int score = row_sum[i] + col_sum[j];
max_score = max(max_score, score);
}
cout << max_score << endl;
return 0;
}
int main() {
int n;
cin >> n;
vector<vector<int>> matrix(n, vector<int>(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> matrix[i][j];
}
}
max_score(n, matrix);
return 0;
}
不同之处
-
新版本写法:
-
使用了范围
for
循环(也称为范围for
或for-each
循环),这种循环引入于 C++11。它使得代码更加简洁和易读。 -
具体代码为:
for (const auto& pos : empty_positions)
。
-
-
旧版本写法:
-
使用了传统的迭代器循环,这种写法在 C++98/03 中使用更为普遍。虽然它功能上等同于范围
for
循环,但显得较为冗长。 -
具体代码为:
for (vector<pair<int, int>>::const_iterator it = empty_positions.begin(); it != empty_positions.end(); ++it)
。 -
并且在循环体内,使用
*it
来访问当前元素。
-
具体改写点
-
for (const auto& pos : empty_positions)
在新版本中被替换为for (vector<pair<int, int>>::const_iterator it = empty_positions.begin(); it != empty_positions.end(); ++it)
。 -
在旧版本中,需要通过
const pair<int, int>& pos = *it
来解引用迭代器访问当前元素,而新版本直接通过pos
访问。
通过使用范围 for
循环,代码变得更加简洁和直观。C++11 及更高版本支持这种更现代化的写法。对于较旧版本的 C++(如 C++98/03),则需要使用迭代器来遍历容器。
这是洛谷上的题P2356 弹珠游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn),这是本人的学习记录罢了,都是非常基础的题分享给大家,做做参考。如果有错误的地方请大家一定要告知本人。再次表示感谢,如果对大家有帮助的话,希望大家点点赞,关注关注。此后会不断的更新。