整数卡片

 题目描述

有 N 张卡片,第 i 张卡上写着整数 Ai​。

你接下来将要进行 M 次操作:

第 𝑗j 次操作有两个参数 Bj​ 和 Cj​,表示这次操作你要

选择最多Bj​张卡片(可以选0张),将选出卡片上的整数改成Cj​。

M次操作结束后,N张卡片上的整数之和的最大值是多少?

【输入格式】

第1行,2个正整数N,M

第2行,N个正整数A1​,A2​,⋯,AN​

接下来𝑀M行,每行两个正整数𝐵𝑗,𝐶𝑗Bj​,Cj​

【输出格式】

输出𝑀M次操作后所有卡片上整数总和的最大值

【输入输出样例#1】

输入#1

3 2
5 1 4
2 3
1 5

输出#1

14

【输入输出样例#2】

输入#2

10 3
1 8 5 7 100 4 52 33 13 5
3 10
4 30
1 4

输出#2

338

【输入输出样例#3】

输入#3

11 3
1 1 1 1 1 1 1 1 1 1 1
3 1000000000
4 1000000000
3 1000000000

输出#3

10000000001

【说明提示】

样例#1说明

第1次操作:B1​=2,C1​=3,可以最多选2张卡改成3。只选择将第2张卡改成3。

第2次操作:B2​=1,C2​=5,可以最多选1张卡改成5。只选择将第2张卡改成5。

最终所有卡上的数总和为5+5+4=14为最大

样例#2说明

第1次操作:B1​=3,C1​=10,可以最多选3张卡改成10。选择第1,3,61,3,6张卡改成10,数组变成 [10,8,10,7,100,10,52,33,13,5][10,8,10,7,100,10,52,33,13,5]。

第2次操作:B2​=4,C2​=30,可以最多选4张卡改成30。选择第1,2,4,101,2,4,10张卡改成30,数组变成 [30,30,10,30,100,10,52,33,13,30][30,30,10,30,100,10,52,33,13,30]。

第3次操作:B3​=1,C3​=4,可以最多选1张卡改成4。这次不选择任何卡,数组不变。

最终所有卡上的数总和为 338

【数据范围】

1≤N≤105

1≤M≤105

1≤Ai​,Cj​≤109

1≤Bj​≤N

---------------------------------------------------------------------------------------------------------------------------------

#include <bits/stdc++.h>
using namespace std;

map<int,int>mp;
int main()
{
    int n,m;
    cin>>n>>m;
    long long sum=0;
    for(int i=1;i<=n;i++)
    {
        int a;
        cin>>a;
        mp[a]++;
        sum+=a;
    }
    while(m--)
    {
        int b,c;
        cin>>b>>c;
        int i=0;
        vector<int> ee;
        for(auto &it:mp)
        {
            if(i==b||it.first>=c)
                break;
            int num=it.second;
            if(b-i<=num)
            {
                mp[c]+=b-i;
                it.second-=b-i;
                sum+=1ll*(b-i)*(c-it.first);
                if( it.second==0)
                    ee.push_back(it.first);
                break;
            }
            it.second-=num;
            i+=num;
            mp[c]+=num;
            sum+=1ll*num*(c-it.first);
            ee.push_back(it.first);
        }
        for(auto k:ee)
            mp.erase(k);
    }
    cout<<sum;
    return 0;
}

---------------------------------------------------------------------------------------------------------------------------------

这道题我前面写的时候问题不大,结果后面写着写着发现超时了,我爸爸说是因为遍历map的时候没有erase。

但是erase之后又RTE了,因为在用AUTO遍历的时候,是不能修改的,会影响红黑树的结构。

所以我开了一个vector,把要erase的下标都存了进去,最后再一块儿erase就好了。

### 蓝桥杯卡片相关题目解析 蓝桥杯竞赛中涉及的“卡片”类问题通常考察选手对于字符串操作、排列组合以及逻辑推理的能力。这类题目往往需要仔细阅读并理解题意,因为稍有偏差可能导致完全不同的解答方向。 #### 题目背景分析 在某些情况下,“卡片”的概念可能被抽象化为组字符或者数字,通过这些字符或数字的不同排列方式形成特定的目标数值或字符串模式[^1]。例如,在给定的卡片上分别有不同的单个数字(如 '1' 和 '0'),可以通过重新排列这些卡片来构建新的数字序列。这种类型的题目重点在于如何有效枚举所有可能性,并从中筛选满足条件的结果。 #### 解决方案概述 针对此类问题的个通用方法是从以下几个方面入手: - **数据结构选择**: 使用数组或其他集合类型的数据结构存储每卡代表的具体值。 - **算法设计**: - 如果目标是找出能够组成的最大/最小数,则需考虑排序策略;比如按降序排列得到最大的数。 - 当涉及到寻找符合条件的所有组合时,递归函数配合回溯技术会非常有用。它允许程序尝试各种可能的状态变化路径直到找到解决方案为止。 以下是基于上述描述的种实现示例: ```java import java.util.*; public class CardArrange { public static void main(String[] args){ List<String> cards = Arrays.asList("1", "0"); // 初始化卡片列表 Set<Integer> results = new HashSet<>(); permute(cards, "", results); System.out.println(results); // 输出所有可拼接出的独特整数 } private static void permute(List<String> remainingCards, String currentNumber, Set<Integer> resultSet){ if(remainingCards.isEmpty()){ resultSet.add(Integer.parseInt(currentNumber)); }else{ for(int i=0;i<remainingCards.size();i++){ ArrayList<String> nextRemaining = new ArrayList<>(remainingCards); String cardValue = nextRemaining.remove(i); permute(nextRemaining, currentNumber + cardValue, resultSet); } } } } ``` 此代码片段展示了如何利用递归来探索由不同卡片组成的所有潜在数字组合。注意这里采用了`HashSet`来保存最终结果以自动去除重复项。 #### 关键点提示 - 对于输入规模较大的情况,应评估所选算法的时间复杂度,必要时优化其性能表现。 - 特殊边界情形处理非常重要,例如当没有任何合法解存在时该如何响应等问题都需要提前规划好。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值