2022年第十三届蓝桥杯题解(全)C/C++

news2025/1/20 14:59:49

A题就是一个简单的进制转化,代码实现如下:

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int main()
{
	int x = 2022;
	int a = 1;
	int res = 0;
	while(x) {
		res += (x % 10) * a;
		a = a * 9;
		x /= 10;
	}
	cout << res;
	
	return 0;
}

B题有很大的争议,我认为顺子的意思是从0开始的至少为三个数的升序序列。那这样的话答案就是:14

C题是一个很普通的思维题,先记录一下每周能做多少题,然后统计一下总的做题数除以每周能做的题然后乘以7,再加上从周一开始计算每一天什么时候能大于这个总的题数的天数即可。

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;

const int N = 1e5 + 10;

int main()
{
	LL a, b, n, t, res;
	cin >> a >> b >> n;
	
	t = a * 5 + b * 2;
	res = n / t * 7;

	n %= t;
	if(n > 0)
		for(int i = 1; i <= 7; i ++ )
		{
			if(i == 6 || i == 7) n -= b;
			else n -= a;
			res ++;
			if(n <= 0) break;
		}
	
	cout << res;
	
	return 0;
}

D题应该是最简单的一道,开一个n的数组a[i],a[i]表示每一个灌木能长得最大高度,最大高度等于它右侧的树木数乘以2;

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;

const int N = 1e4 + 10;

int a[N], n;

int main()
{
	cin >> n;
	for(int i = 1; i <= (n + 1) / 2; i ++ ) {
		a[i] = (n - i) * 2;
		a[n - i + 1] = a[i];
	}
	
	for(int i = 1; i <= n; i ++ ) {
		cout << a[i];
		if(i != n) cout << "\n";
	}
	
	return 0;
}

E题就开始有点意思了,这道题是一个简单贪心,重点在于读题(其实接触过这个进制问题的童鞋应该一样就看懂了emmm)。

我们先分析一下题干的65是怎么出来的:第一数位每一个数代表的必然是1,第二数位是由第一数位的二进制晋上来的,所以第二数位每一个数代表的是2,第三数位是由第二数位十进制进位上来的,所以第三数位每一个数代表的是2 * 10 = 20,所以这个x(321) = 3 * 20 + 2 * 2 + 1 * 1 = 65;

题目的意思是保证x(a) >= x(b) , 求两个数的差值最小。显然对于每一数位,其进制越小,两个数的后一数位做差所得到的值越小,所以每一数位最小的合法进制数就行。

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int mod = 1e9 + 7, N = 1e5 + 10;

int a[N], b[N];
int ma, mb, n;

signed main()
{
	cin >> n;
	cin >> ma;
	for(int i = 1; i <= ma; i ++ ) cin >> a[i];
	for(int i = 1; i <= ma / 2; i ++ ) swap(a[i], a[ma - i + 1]);
	
	cin >> mb;
	for(int i = 1; i <= mb; i ++ ) cin >> b[i];
	for(int i = 1; i <= mb / 2; i ++ ) swap(b[i], b[mb - i + 1]); 
	
	int t = 1, ans = 0;
	//枚举每个数位
	for(int i = 1; i <= ma; i ++ ) {
		//当前数位贪心最优的进制 
		int z = max(a[i], b[i]) + 1;
		if(z < 2) z = 2; 
		ans += a[i] * t - b[i] * t;
		ans %= mod;
		t = t * z % mod;
	}
	
	cout << ans;
	
	return 0;
}

F题可以暴力写一下,求一个前缀和,然后枚举子矩阵,时间复杂度是O(n^4), 显然过不了;

这个题考的是一个双指针,枚举一下矩阵中的左右边界,在每一个左右边界中,从上往下求一下子段中小于等于k的数的数量(用双指针扫一下就可以,这一步可以做到o(n));

时间复杂度:O(n ^ 3)

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(fast)
#include <bits/stdc++.h>

using namespace std;

const int N = 510;
typedef long long LL;

int a[N][N];

int main()
{
    int n, m, k;
    scanf("%d%d%d", &n, &m, &k);
    
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= m; j ++ )
            scanf("%d", &a[i][j]);
            
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= m; j ++ )
            a[i][j] += a[i][j - 1];
    
    LL cnt = 0;
    for(int i = 1; i <= m; i ++ )
        for(int j = i; j <= m; j ++ ) {
            int res = 0;
            for(int l = 1, r = 1; r <= n; r ++ ) {
                res += a[r][j] - a[r][i - 1];
                while(res > k && l <= r) {
                    res -= a[l][j] - a[l][i - 1];
                    l ++;
                }
                if(res <= k && l <= r) cnt += r - l + 1;
            } 
        }
    printf("%lld", cnt);
    
    
    return 0;
}

这个题考的是一个dp;

状态表示: f[i][j]表示前i列积木中,第i列状态为j的情况数。

四种情况:j = 0, 表示当前列为空, 1表示当前列上面有一个格子,2表示当前列下面有一个格子,3表示当前列已满。

由于数据很大,开一个4e8的空间会爆,可以用p来表示上一层状态,q来表示当前层的状态,类似于背包的滚动数组优化。

状态转移看一下代码吧,我感觉还是比较好理解的,不懂的可以评论区问我

#include <bits/stdc++.h>

using namespace std;
typedef long long LL; 

const int N = 1e7 + 10, mod = 1e9 + 7;

LL p[4], q[4];

int main()
{
	int n;
	cin >> n;
	
	p[3] = 1;
	for(int i = 1; i <= n; i ++ ) {
		q[3] = (p[0] + p[1] + p[2] + p[3]) % mod;
		q[0] = p[3] % mod;
		q[1] = (p[0] + p[2]) % mod;
		q[2] = (p[0] + p[1]) % mod;
		for(int i = 0; i <= 3; i ++ )
		    p[i] = q[i];
	}
	cout << p[3];
	return 0;
}

ps:题不可以用并查集去做,因为雷的爆炸是由方向的,A雷爆炸可以引爆B雷,但是B雷爆炸是有可能无法引爆B雷的(爆炸半径不同)

ps:我补题的时候被卡常卡了一天,最后把idx.find改成idx.count就过了(emm55555)

正解是dfs,为了避免边被卡成O(n * n), 以至于tle,我们就需要去除重复的点,记录每一个坐标下点的位置.

然后把每一个火箭作为根节点,去遍历周围r ^ 2的雷,统计一下一共能炸多少雷就可以。

O(100 * n + m)最坏情况为每一个雷有100条边;

#pragma GCC optimize(2)
#include <bits/stdc++.h>

using namespace std;
typedef long long LL;

const int N = 2e5 + 10;

struct Node {
    int x, y, r, l;
}a[N];
//x,y到下标的映射
unordered_map<LL, int> idx;
bool st[N];
int n, m, cnt;
int ans;

LL cal(int x, int y) {
    return (LL)x * (1000000000 + 1) + y;
}

bool solve(int x, int y, int r) {
    if(x * x + y * y <= r * r) return true;
    else return false;
}

void dfs(int i)
{
    //标记当前点
    st[i] = true;
    //加上当前点雷的数量
    ans += a[i].l;
    int r = a[i].r;
    //printf("%d %d %d\n", a[i].x, a[i].y, a[i].r);
    //遍历当前点周围是否有没遍历的子节点,有的话继续dfs
    for(int x = max(a[i].x - r, 0); x <= min(a[i].x + r, 1000000000); x ++ ) {
        for(int y = max(a[i].y - r, 0); y <= min(a[i].y + r, 1000000000); y ++ ) {
            if(solve(x - a[i].x, y - a[i].y, r)) {
                LL xy = cal(x, y);
                if(idx.count(xy)) {
                    int u = idx[xy];
                    if(!st[u]) {
                        dfs(u);
                        //printf("%d\n", u);
                    }
                }
            }
        }
    }
    
}

int main()
{
    scanf("%d%d", &n, &m);
    
    for(int i = 1; i <= n; i ++ ) {
        int x, y, r;
        scanf("%d%d%d", &x, &y, &r);
        LL xy = cal(x, y);
        //如果没有这个点
        if(idx.find(xy) == idx.end()) {
            //将这个点存入idx数组
            idx[xy] = ++cnt; 
            //将这个点存入a数组
            a[cnt] = {x, y, r, 1};
        }
        else {
            int u = idx[xy];
            //这个点已经存在并且半径更大,则会更新这个以前点的编号下的r的值
            a[u].r = max(a[u].r, r);
            //这个点的出现次数加一
            ++ a[u].l;
        }
        //int u = idx[xy];
        //printf("%d %d %d %d\n", a[u].x, a[u].y, a[u].r, a[u].l);
    }
    for(int i = 1; i <= m; i ++ ) {
        int x, y, r;
        scanf("%d%d%d", &x, &y, &r);
        //将这个点加入a中作为起始点,去搜一下其他的雷
        a[cnt + 1] = {x, y, r};
        dfs(cnt + 1);
    }
    printf("%d", ans);
    
    return 0;
}

I题又是一个dp,这个dp感觉比上面那个简单一点;

状态表示:f[i][j][k]表示访问前i个位置时,恰好访问j个店并且酒量恰好为k的时候的方案数;

准确来说这个做法并不能维护所有前i个位置恰好访问j个店的方案数,但是题目只问最后一次遇到花且恰好把酒喝光的次数,所以对于大于100的酒量的状态就不用转移了,因为在后面接近100个位置中,全看花也不能把酒喝完。

状态转移; 看花 : f[i][j][k] = f[i - 1][j][k + 1] 遇店 : f[i][j][k] = f[i - 1][j - 1][k / 2];//注意边界!不要越界

#include <bits/stdc++.h>

using namespace std;

const int N = 110, mod = 1e9 + 7;

//前i次访问,访问j个店的酒量是多少
long long f[N * 2][N][110];

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    
    f[0][0][2] = 1;
    for(int i = 1; i < n + m; i ++ )
        for(int j = 0; j <= n; j ++ )
            for(int k = 0; k <= 100; k ++ ) {
                f[i][j][k] = (f[i][j][k] + f[i - 1][j][k + 1]) % mod;
                if((k % 2 == 0) && j) f[i][j][k] = (f[i][j][k] + f[i - 1][j - 1][k / 2]) % mod;
            }
    printf("%lld", f[n + m - 1][n][1]);
    
    return 0;
}

这个题有两个做法,一种是用set或者堆来维护一个高度到区间的映射,另一个用并查集维护区间,这个做法我没做出来,我用了两个set来做,果然被卡常了.

正解:这个题本质是一个最长公共下降子序列的问题,对于任意一个h,只要它高度降到了与前一个高度下降过程中的公共值,那么它就不需要花费代价继续下降。如果它降得的当前高度与前一个高度没有公共值,则需要多花费一个代价,来降低自己的高度。我们只需要开两个数组暴力做一下就行。

时间复杂度: O(n);

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;

const int N = 2e5 + 10;

LL a[N];
vector<LL> b[N];
int n;

LL solve(LL x) {
    return sqrt(x / 2 + 1);
}

int main() {
    scanf("%d", &n);

    for(int i = 1; i <= n; i ++ ) scanf("%lld", &a[i]);

    int res = 0;

    for(int i = 1; i <= n; i ++ ) {
        while(a[i] > 1) {
            int flag = 0;
            for(LL j : b[i - 1]) {
                if(a[i] == j) {
                    flag = 1;
                    break;
                }
            }
            if(!flag) res ++;
            b[i].push_back(a[i]);
            a[i] = solve(a[i]);
        }

    }
    printf("%d", res);

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/414576.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【论文阅读笔记】COFFEE: A Contrastive Oracle-Free Framework for Event Extraction

论文题目&#xff1a;COFFEE: A Contrastive Oracle-Free Framework for Event Extraction 论文来源&#xff1a; 论文链接&#xff1a;https://arxiv.org/pdf/2303.14452.pdf 代码链接&#xff1a; 0 摘要 事件抽取是一项复杂的信息抽取任务&#xff0c;它涉及到从非结构…

【AIGC】7、CLIP | OpenAI 出品使用 4 亿样本训练的图文匹配模型

文章目录一、背景二、方法2.1 使用自然语言来监督训练2.2 建立一个超大数据集2.3 选择预训练模型2.4 模型缩放和选择三、效果论文&#xff1a;Learning Transferable Visual Models From Natural Language Supervision 代码&#xff1a;https://github.com/OpenAI/CLIP 官网&…

DJ3-5 死锁概述

目录 3.5 死锁概述 3.5.2 计算机系统中的死锁 1. 竞争资源 2. 进程推进顺序不当 3.5.3 死锁的必要条件和处理方法 1. 死锁的必要条件 2. 处理死锁的方法 3.6 预防死锁 3.6.1 摒弃 “请求和保持” 条件 3.6.2 摒弃 “不剥夺” 条件 3.6.3 摒弃 “环路等待” 条…

企业在数字化建设中,BI 处于什么位置?

对市场异常敏感的商业世界自然不会放过获取数字经济的机会&#xff0c;在众多企业开始进行数字化转型&#xff0c;通过信息化建设&#xff0c;部署BI来完成转型工作。 很多人都听说过BI&#xff0c; 但是并不太清楚BI 在IT信息化中到底处于一个什么位置&#xff1f;有很多的疑…

APIs --- DOM基础事件

1. 事件 事件是编程时系统内发生的动作或者发生的事情&#xff0c;它是用来描述程序的行为或状态的&#xff0c;一旦行为或状态发生改变&#xff0c;便立即调用一个函数。 例如&#xff1a;用户使用【鼠标点击】网页中的一个按钮、用户使用【鼠标拖拽】网页中的一张图片 事件…

【MySQL】外键约束和外键策略

一、什么是外键约束&#xff1f; 外键约束&#xff08;FOREIGN KEY&#xff0c;缩写FK&#xff09;是用来实现数据库表的参照完整性的。外键约束可以使两张表紧密的结合起来&#xff0c;特别是针对修改或者删除的级联操作时&#xff0c;会保证数据的完整性。 外键是指表…

ElasticSearch——详细看看ES集群的启动流程

参考&#xff1a;一起看看ES集群的启动流程 本文主要从流程上介绍整个集群是如何启动的&#xff0c;集群状态如何从Red变成Green&#xff0c;然后分析其他模块的流程。 这里的集群启动过程指集群完全重启时的启动过程&#xff0c;期间要经历选举主节点、主分片、数据恢复等重…

java中的SPI机制

文章目录SPI 介绍何谓 SPI?SPI 和 API 有什么区别&#xff1f;实战演示Service Provider InterfaceService Provider效果展示ServiceLoaderServiceLoader 具体实现自己实现一个 ServiceLoader总结在面向对象的设计原则中&#xff0c;一般推荐模块之间基于接口编程&#xff0c;…

测试开发备战秋招面试3

努力了那么多年,回头一望,几乎全是漫长的挫折和煎熬。对于大多数人的一生来说,顺风顺水只是偶尔,挫折、不堪、焦虑和迷茫才是主旋律。我们登上并非我们所选择的舞台,演出并非我们所选择的剧本。继续加油吧&#xff01; 目录 1.讲一下redis和mySQL的区别&#xff1f; 2.讲一下…

ChatGPT让现在的软件都土掉渣了

我们家有两个娃&#xff0c;每次我们想要出去时订个酒店时都好麻烦。我在某程上找&#xff0c;我先看有没有家庭房&#xff0c;但家庭房很少&#xff0c;而且有些家庭房实际上只能睡得下两大一小。普通房间能不能睡得下四个人&#xff0c;那可是得查看很多信息&#xff0c;如床…

Redis队列Stream、Redis多线程详解(一)

Redis队列与Stream Redis5.0 最大的新特性就是多出了一个数据结构 Stream&#xff0c;它是一个新的强大的支持多播的可持久化的消息队列&#xff0c;作者声明Redis Stream地借鉴了 Kafka 的设计。 Redis Stream 的结构如上图所示,每一个Stream都有一个消息链表&#xff0c;将所…

Pandas 学习手册中文第二版:1~5

原文&#xff1a;Learning pandas 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 一、Pandas 与数据分析 欢迎来到《Pandas 学习手册》&#xff01; 在本书中&#xff0c;我们将进行一次探索我们学习 Pandas 的旅程&#xff0c;这是一种用于 Python 编程语言的开源数…

Android:启动流程

Android启动流程 第一步&#xff1a;启动电源以及系统启动 当电源按下&#xff0c;引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序到RAM&#xff0c;然后 执行 第二步&#xff1a;引导程序 引导程序是在Android操作系统开始运行前的一个小程序。引导程序…

如何防止设备被重复控制

1. 引言 在一个物联网的系统中&#xff0c;主要有三部分组成&#xff1a;云端、WiFi、电控。当用户在APP上控制设备时&#xff0c;其控制下发链路是&#xff1a;云端>>WIFI>> 电控。当电控收到控制指令后&#xff0c;执行设备控制&#xff0c;控制成功后&#xff…

如何使用Midjourney辅助建筑平面设计,常用的建筑平面效果图提示和使用效果展示(内附Midjourney提示词网站)

文章目录一、室内建筑平面设计1.AutoCAD图纸&#xff08;别墅首层图&#xff09;2.平面效果图3.三维平面透视图二、建筑室内设计1.现代简约2.波西米亚风格3.工业风格4.沿海风格5.法国风格6.现代风格7.提示增加颜色倾向8.提示中增加设计师9.其它一些尝试三、好用的Midjourney提示…

Redis 6.x哨兵模式部署(五)

目录 一、主从复架构搭建 二、哨兵模式搭建 2.1背景 2.2哨兵模式介绍 2.3 Sentinel三大工作任务 1监控&#xff08;Monitoring&#xff09; 2提醒&#xff08;Notification&#xff09; 3自动故障迁移&#xff08;Automatic failover&#xff09; 4核心流程 2.4 安装…

企业如何实现数字化转型?

企业如何实现数字化转型&#xff1f; 首先&#xff0c;我需要先跟各位明确&#xff0c;企业数字化转型中很重要的3个“先行”条件&#xff1a; 第一、企业一把手的眼光和格局 一把手的视野、格局、定力是最重要的因素&#xff0c;没有之一。能不能放下自己过去的执念与经验&a…

信息与计算科学有哪些SCI期刊推荐? - 易智编译EaseEditing

以下是信息与计算科学领域的一些知名SCI期刊推荐&#xff1a; Information Sciences&#xff1a; 该期刊是信息科学领域的重要期刊&#xff0c;涵盖了信息科学、计算科学、人工智能、数据挖掘、模式识别、多媒体技术、网络通信、智能系统等方面的研究。 IEEE Transactions on…

电子文件的线上存储工具,你了解多少?

信息化时代的来临&#xff0c;企业也纷纷跟随时代步伐进入现代化办公。信息时代最显著的特征就是纸质文件到电子文件的转变。企业一天的办公中&#xff0c;可能就会产出无数的电子文件&#xff0c;其中很多文件都是珍贵的业务经验&#xff0c;因此线上存储是企业需要考虑的问题…

网页解析--bs4--01

python爬虫之bs4模块&#xff08;超详细&#xff09; Beautiful Soup 4.4.0 文档 — Beautiful Soup 4.2.0 documentation (crummy.com) 可以看到bs4库将网页文件变成了一个soup的类型&#xff0c; 事实上&#xff0c;bs4库 是解析、遍历、维护、“标签树“的功能库。 通俗一点…