2021年第十二届蓝桥杯第三场校模拟赛最后三个题题解简单易懂版C++

由于前7个题太简单了,所以本篇文章就不特意去做前七个题的题解了。其实是我自己把做完的代码删掉,然后懒得重新写了
咳咳,进入正题。

第八题

这个题我就讲下思路
用到了二维前缀和
先预处理出数组的二维前缀和,之后直接根据题意判断就行了
如果不会求二维前缀和的可以看看以下博客
传送门

第九题

时间限制: 3.0s 内存限制: 512.0MB 本题总分:25 分

  • 【问题描述】

杂货铺老板一共有N件物品,每件物品具有ABC三种属性中的一种或多种。从杂货铺老板处购得一件物品需要支付相应的代价。
现在你需要计算出如何购买物品,可以使得ABC三种属性中的每一种都在至少一件购买的物品中出现,并且支付的总代价最小。

  • 输入格式

输入第一行包含一个整数N。
以下N行,每行包含一个整数C和一个只包含"ABC"的字符串,代表购得该物品的代价和其具有的属性。

  • 输出格式

输出一个整数,代表最小的代价。如果无论如何凑不齐ABC三种属性,输出-1。

解题思路
因为字母最多只有三个,它们最多有3 + 6 + 6 = 15种情况

一个字母 : A、B、C
两个字母 :AB(BA)、AC(CA)、BC(CB)
三个字母 :ABC(ACB、BAC、BCA、CAB、CBA)
这里我把相同字母但是顺序不同的单词括了起来,因为题目要求只要有ABC三种属性而且值最小就行了,所以顺序无关。我这里把具有相同字母但是顺序不同的定义为相同的“状态”(下方统称状态)

所以我们可以暴力出所有情况,把相同状态相同的单词存在哈希表中,然后每一次读入数据的时候,去更新状态相同的单词的值,让它取min,这样就保证了相同状态的单词取到了最小值。(默认每各单词的初始值为最大值,我这里定义为0x3f3f3f3f,因为如果最后结果为这个最大值,说明没有题目所要求的,所以这种情况应该输出-1
读入结束后判断每一个可以凑成ABC的状态单词。之后取最小值就行。
如果还是不懂可以结合代码看一遍,应该很容易理解的。

AC代码

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;

const int INF = 0x3f3f3f3f;
unordered_map<string, int> mp{{"A", INF}, {"B", INF}, {"C", INF}, {"AB", INF}, {"AC", INF}, {"BC", INF}, {"ABC", INF}};

int main(){
    int n;
    cin >> n;
    while(n--){
        int w;
        string s;
        cin >> w >> s;
        if(s == "AB" || s == "BA") mp["AB"] = min(mp["AB"], w);
        else if(s == "AC" || s == "CA") mp["AC"] = min(mp["AC"], w);
        else if(s == "BC" || s == "CB") mp["BC"] = min(mp["BC"], w);
        else if(s == "ABC" || s == "ACB" || s == "BAC" || s == "BCA" || s == "CAB" || s == "CBA") mp["ABC"] = min(mp["ABC"], w);
        else mp[s] = min(mp[s], w);
    }

    int ans = 0x3f3f3f3f;
    ans = min(ans, mp["A"] + mp["BC"]);
    ans = min(ans, mp["B"] + mp["AC"]);
    ans = min(ans, mp["C"] + mp["AB"]);
    ans = min(ans, mp["ABC"]);
    ans = min(ans, mp["A"] + mp["B"] + mp["C"]);
    
    if(ans == INF) puts("-1");
    else printf("%d", ans);
    return 0;
}

第十题

emmm还没写呢
等我写了再来更新吧~~~
嗯嗯就这样

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

就一枚小白

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

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

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

打赏作者

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

抵扣说明:

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

余额充值