B3928 [GESP202312 四级] 田忌赛马

[GESP202312 四级] 田忌赛马

题目描述

你要和田忌赛马。你们各自有 N N N 匹马,并且要进行 N N N 轮比赛,每轮比赛,你们都要各派出一匹马决出胜负。

你的马匹的速度分别为 u 1 , u 2 , ⋯ , u n u_1,u_2,\cdots,u_n u1,u2,un,田忌的马匹的速度分别为 v 1 , v 2 , ⋯   , v n v_1,v_2,\cdots,v_n v1,v2,,vn。田忌会按顺序派出他的马匹,请问你要如何排兵布阵,才能赢得最多轮次的比赛?巧合的是,你和田忌的所有马匹的速度两两不同,因此不可能出现平局。

输入格式

第一行一个整数 N N N。保证 1 ≤ N ≤ 5 × 1 0 4 1\le N \le 5\times 10^4 1N5×104

接下来一行 N N N 个用空格隔开的整数,依次为 u 1 , u 2 , ⋯   , u n u_1,u_2,\cdots,u_n u1,u2,,un,表示你的马匹们的速度。保证 1 ≤ u i ≤ 2 N 1\le u_i\le 2N 1ui2N

接下来一行 N N N 个用空格隔开的整数,依次为 v 1 , v 2 , ⋯   , v n v_1,v_2,\cdots,v_n v1,v2,,vn,表示田忌的马匹们的速度。保证 1 ≤ v i ≤ 2 N 1\le v_i\le 2N 1vi2N

输出格式

输出一行,表示你最多能获胜几轮。

样例 #1

样例输入 #1

3
1 3 5
2 4 6

样例输出 #1

2

样例 #2

样例输入 #2

5
10 3 5 8 7
4 6 1 2 9

样例输出 #2

5

提示

样例解释 1

第 1 轮,田忌派出速度为 2 的马匹,你可以派出速度为 3 的马匹迎战,本轮你获胜。

第 2 轮,田忌派出速度为 4 的马匹,你可以派出速度为 5 的马匹迎战,本轮你获胜。

第 3 轮,田忌派出速度为 6 的马匹,你可以派出速度为 1 的马匹迎战,本轮田忌获胜。

如此,你可以赢得 2 轮比赛。

解析

题目描述:
你要和田忌赛马。你们各自有N匹马,并且要进行N轮比赛,每轮比赛,你们都要各派出一匹马决出胜负。你的马匹的速度分别为u1,u2,…,un,田忌的马匹的速度分别为v1,v2,…,vn。田忌会按顺序派出他的马匹,请问你要如何排兵布阵,才能赢得最多轮次的比赛?巧合的是,你和田忌的所有马匹的速度两两不同,因此不可能出现平局。

解题思路:
这是一个经典的贪心算法问题。我们可以按照以下策略来安排比赛:

  1. 将你的马匹按速度从小到大排序,将田忌的马匹按速度从小到大排序。
  2. 从速度最慢的马匹开始,每次选择你的马匹中速度最慢且能够战胜田忌当前马匹的马匹出战。
  3. 如果你没有马匹能够战胜田忌当前的马匹,则选择你最慢的马匹出战。

这种策略的思路是,尽可能用较慢的马匹去战胜田忌的马匹,从而节省更快的马匹来对付田忌的更快的马匹。

C++代码实现:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int N;
    cin >> N;
    
    vector<int> u(N), v(N);
    for (int i = 0; i < N; ++i) {
        cin >> u[i];
    }
    for (int i = 0; i < N; ++i) {
        cin >> v[i];
    }
    
    sort(u.begin(), u.end());
    sort(v.begin(), v.end());
    
    int i = 0, j = 0, wins = 0;
    while (i < N && j < N) {
        if (u[i] > v[j]) {
            ++wins;
            ++j;
        }
        ++i;
    }
    
    cout << wins << endl;
    
    return 0;
}

代码解释:

  1. 读入数据,包括马匹数量N,以及你的马匹速度向量u和田忌的马匹速度向量v。
  2. 使用sort函数对向量u和v分别进行排序。
  3. 定义指针i和j,分别指向向量u和v的起始位置,定义计数变量wins,初始值为0。
  4. 使用while循环,同时遍历向量u和v:
    • 如果u[i] > v[j],说明你的当前最慢的马匹能够战胜田忌的当前马匹,将wins加1,并将j向后移动一位。
    • 无论是否获胜,将i向后移动一位,表示你的当前马匹已经出战。
  5. 输出wins的值,即为你能够获胜的最多轮数。

这个解法的时间复杂度为O(NlogN),主要是排序的时间复杂度。空间复杂度为O(N),需要存储两个向量。

与之前的解法相比,这个解法使用了C++的STL向量(vector)和算法(algorithm)库,代码更加简洁易读。同时,在遍历向量时,使用了while循环和两个指针i和j,避免了不必要的比较和移动操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天秀信奥编程培训

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值