#3洛谷题目分享(P2356 弹珠游戏)

目录

1.题目背景

题目描述

输入格式

输出格式

样例 #1

样例输入 #1

样例输出 #1

提示

2.代码

3.注意

新版本写法(使用范围for循环):

旧版本写法(使用迭代器):

不同之处

具体改写点


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;
}

 
  1. 包含头文件和使用命名空间

    • #include <iostream>:包含输入输出流库,用于标准输入输出。

    • #include <vector>:包含向量库,用于动态数组。

    • using namespace std;:使用标准命名空间,避免使用 std:: 前缀。

  2. 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" 并返回。

    • 计算最大分数

      • 使用迭代器遍历所有空位置,计算每个空位置的分数,并更新最大分数。

    • 输出结果

      • 输出计算得到的最大分数。

  3. 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;
}

不同之处

  1. 新版本写法

    • 使用了范围 for 循环(也称为范围 forfor-each 循环),这种循环引入于 C++11。它使得代码更加简洁和易读。

    • 具体代码为:for (const auto& pos : empty_positions)

  2. 旧版本写法

    • 使用了传统的迭代器循环,这种写法在 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),这是本人的学习记录罢了,都是非常基础的题分享给大家,做做参考。如果有错误的地方请大家一定要告知本人。再次表示感谢,如果对大家有帮助的话,希望大家点点赞,关注关注。此后会不断的更新。

  • 43
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值