1. 题目描述

1.1. Limit

Time Limit: 1000 ms

Memory Limit: 524288 kB

1.2. Problem Description

蒜头君在玩一种卡牌游戏,他有 n n n 张卡牌,每张卡牌上写着两个正整数 a i , b i a_i, b_i ai,bi a i a_i ai 表示这张卡牌的能量值, b i b_i bi 表示这张卡牌的魔法值。

他准备一张一张打出这 n n n 张卡牌,每张卡牌会对敌人造成的伤害是这张卡牌的能量值乘魔法值。但是蒜头君觉得这样把这 n n n 张卡牌都出完对敌人造成的伤害之和还是不够大,所以他偷偷学会了一种仙术。

蒜头君施展一次仙术的时候会任意选择两张卡牌,把它们的魔法值交换,能量值不交换。蒜头君可以使用任意次仙术,当然也可以一次都不使用,他想知道使用了若干次仙术以后一张一张打出这 n n n 张卡牌,对敌人造成的伤害之和最大是多少。


1.3. Input

第一行,一个正整数 n n n ( 1 n 1 0 5 ) (1 \le n \le 10^5) (1n105)

接下来 n n n 行,每行两个正整数 a i , b i a_i, b_i ai,bi ( 1 a i , b i 1 0 6 ) (1 \le a_i, b_i \le 10^6) (1ai,bi106)


1.4. Output

输出一行,包含一个整数,表示蒜头君使用若干次仙术以后一张一张打出卡牌,对敌人造成的伤害之和的最大值。


1.5. Sample Input

3
1 6
3 4
5 2

1.6. Sample Output

44

1.7. Source

计蒜客 T3058 卡牌游戏 IV


2. 解读

STL基本使用。

使用 priority_queue 对数据进行存储和排序,将能量值 a i a_i ai 和魔法值 b i b_i bi 分别存储在两个不同的优先队列中,降序排列。

a i a_i ai 中的最大值和 b i b_i bi 中的最大值相乘,将结果存储在 a n s ans ans 中。然后将两个最大值出队,将剩余的 a i a_i ai b i b_i bi 中的最大值继续相乘,累加在 a n s ans ans 中,直到队列为空,最后输出 a n s ans ans

3. 代码

#include <iostream>
#include <queue>
#include <string.h>
using namespace std;

//降序队列a
priority_queue<long long> aQueue;
//降序队列b
priority_queue<long long> bQueue;

int main()
{
    // test case
    int t;
    scanf("%d", &t);
    // 输入buffer
    long long a, b;
    // 存储结果
    long long ans = 0l;
    // 输入
    for (int i = 0; i < t; i++) {
        scanf("%lld %lld", &a, &b);
        // 放入优先队列
        aQueue.push(a);
        bQueue.push(b);
    }
    // 组合
    for (int i = 0; i < t; i++)
    {
        // 乘积累加
        ans += aQueue.top() * bQueue.top();
        // 队首元素出队
        aQueue.pop();
        bQueue.pop();
    }

    // 输出
    printf("%lld\n", ans);
}


联系邮箱:curren_wong@163.com

Github:https://github.com/CurrenWong

欢迎转载/Star/Fork,有问题欢迎通过邮箱交流。