蓝桥杯C++大学B组一个月冲刺记录2024/3/18
蓝桥杯C++大学B组一个月冲刺记录2024/3/18
规则:每日三题
昨天因为前妻姐emo上了,静下来思考了点东西,就没做题啦.今日补上!
另外:博客浏览量破万了,写的东西有人看还是很开心的
1.母亲的牛奶
农夫约翰有三个容量分别为 A,B,C升的挤奶桶。
最开始桶 A和桶 B都是空的,而桶 C里装满了牛奶。
有时,约翰会将牛奶从一个桶倒到另一个桶中,直到被倒入牛奶的桶满了或者倒出牛奶的桶空了为止。
这一过程中间不能有任何停顿,并且不会有任何牛奶的浪费。
请你编写一个程序判断,当 A桶是空的时候,C桶中可能包含多少升牛奶,找出所有的可能情况。
bfs + 状态转移
主要思想:
(1)是如何记录被遍历的状态,任何字符串(或是多数据)的状态,都可以通过各元素元素编码得到一个longlong值.然后通过哈希进行记录
(2)状态转移:穷举即可
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>using namespace std;const int N = 25;int A,B,C;struct state{int a,b,c;
};bool st[N * N * N];vector<int>ans;int query_k(int a, int b, int c){return a * 21 * 21 + b * 21 + c;
}void bfs(int a,int b,int c){int k = query_k(a,b,c);st[k] = true;queue<state>q;q.push({a,b,c});while(q.size() != 0){auto t = q.front();q.pop();if(t.a == 0) ans.push_back(t.c); if(t.a != 0){state New;New.a = t.a - min(t.a,B - t.b);New.b = t.b + min(t.a,B - t.b);New.c = t.c;k = query_k(New.a,New.b,New.c);if(!st[k]) q.push(New),st[k] = true;New.a = t.a - min(t.a,C - t.c);New.b = t.b;New.c = t.c + min(t.a,C - t.c);;k = query_k(New.a,New.b,New.c);if(!st[k]) q.push(New),st[k] = true;}if(t.b != 0){state New;New.a = t.a + min(t.b,A - t.a);New.b = t.b - min(t.b,A - t.a);New.c = t.c;k = query_k(New.a,New.b,New.c);if(!st[k]) q.push(New),st[k] = true;New.a = t.a;New.b = t.b - min(t.b,C - t.c);New.c = t.c + min(t.b,C - t.c);;k = query_k(t.a,t.b,t.c);if(!st[k]) q.push(New),st[k] = true;}if(t.c != 0){state New;New.a = t.a + min(t.c,A - t.a);New.b = t.b;New.c = t.c - min(t.c,A - t.a);k = query_k(New.a,New.b,New.c);if(!st[k]) q.push(New),st[k] = true;New.a = t.a;New.b = t.b + min(t.c,B - t.b);New.c = t.c - min(t.c,B - t.b);;k = query_k(New.a,New.b,New.c);if(!st[k]) q.push(New),st[k] = true;}}return;}int main(){cin >> A >> B >> C;bfs(0,0,C);sort(ans.begin(),ans.end());for(int i = 0;i < ans.size();++i) cout << ans[i] << ' ';return 0;
}
2.走迷宫
给定一个 n×m的二维整数数组,用来表示一个迷宫,数组中只包含 0
或 1,其中 0表示可以走的路,1 表示不可通过的墙壁。
最初,有一个人位于左上角 (1,1)处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。
请问,该人从左上角移动至右下角 (n,m)处,至少需要移动多少次。
数据保证 (1,1)处和 (n,m)处的数字为 0,且一定至少存在一条通路。
bfs
简单的bfs,求最短路
#include<iostream>
#include<queue>
#include<cstdio>using namespace std;const int M = 105;typedef pair<int,int>PII;int p[M][M];int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};bool st[M][M];
int dist[M][M];int m,n;void bfs(int x,int y){st[x][y] = true;queue<PII>q;q.push({x,y});while(q.size() != 0){auto t = q.front();q.pop();if(t.first == m && t.second == n) break;for(int i = 0;i < 4; ++i){ int xx = t.first + dx[i];int yy = t.second + dy[i];if(xx >= 1 && xx <= m && yy >= 1 && yy <= n && p[xx][yy] == 0 && !st[xx][yy]){st[xx][yy] = true;dist[xx][yy] = dist[t.first][t.second] + 1;q.push({xx,yy});}}}return;
}int main(){cin >> m >> n;for(int i = 1;i <= m;++i){for(int j = 1;j <= n;++j){cin >> p[i][j];}}bfs(1,1);cout << dist[m][n] << endl;return 0;
}
3.八数码(1)
经典的华容道问题:不贴了.
求的是到达最终形态的最小操作数
bfs + 状态转移
更经典的状态记录:各元素加权求和然后哈希
这个哈希可以直接使用unorder_map数据结构来做.
但是为了锻炼手写哈希散列表的能力:我选择手写
(手写哈希的耗时只有unorder_map的三分之一,unorder_map的底层是红黑树)
手写哈希耗时1608ms
unorder_map耗时:2312ms
#include<iostream>
#include<queue>
#include<cstring>using namespace std;const int N = 1e6 + 3;typedef long long LL;LL h[N];int dist[N];int dx[4] = {0,1,0,-1},dy[4] = {1,0,-1,0};LL query_k(string s){LL t = 0;for(int i = 0;i < s.size(); ++i) t = t * 10 + s[i] - '0';return t;}int find(string s){LL t = query_k(s);int k = (t % N + N) % N;while(h[k] != -1 && h[k] != t){k++;if(k >= N) k = 0;}return k;
}int bfs(string first){string end = "123456789";queue<string>q;q.push(first);h[find(first)] = query_k(first); while(q.size() != 0){int old_k,new_k;auto t = q.front();q.pop();old_k = find(t);if(t == end) return dist[old_k];int id = t.find('9');int x = id / 3,y = id % 3; for(int i = 0; i < 4; ++i){int xx = x + dx[i];int yy = y + dy[i];if(xx >= 0 && xx < 3 && yy >= 0 && yy < 3){swap(t[xx * 3 + yy],t[id]);new_k = find(t);if(h[new_k] == -1){q.push(t);h[new_k] = query_k(t);dist[new_k] = dist[old_k] + 1; }swap(t[xx * 3 + yy],t[id]);} }}return -1;
}int main(){memset(h,-1,sizeof(h));string first;for(int i = 1;i <= 9;++i){char c;cin >> c;if(c == 'x') first += '9';else first += c;}cout << bfs(first) << endl;return 0;}
4.全球变暖
你有一张某海域 N×N 像素的照片,”.”表示海洋、”#”表示陆地,如下所示:
…
.##…
.##…
…##.
…####.
…###.
…
其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿,例如上图就有 2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。
具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
…
…
…
…
…#…
…
…
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
染色法+bfs
简单的染色法前后计算岛屿的个数,然后做差值是错误的. 原因:可能存在岛屿被水淹没后,形成了两个岛屿,让岛屿的数量增加.
主要思想: 在染色过程中,计算在该岛屿是否存在土地四周没有海洋,即该土地不会被水淹没,即该岛屿不会被淹没.
#include<iostream>
#include<queue>using namespace std;typedef pair<int,int>PII;const int M = 1005;char p[M][M];
bool st[M][M];
bool f[M * M];int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};int n,cnt;void bfs(int i,int j){st[i][j] = true;cnt ++;queue<PII>q;q.push({i,j});while(q.size() != 0){auto t = q.front();q.pop();bool flag = false;for(int k = 0;k < 4; ++k){int xx = t.first + dx[k];int yy = t.second + dy[k];if(xx >= 0 && xx < n&& yy >= 0&& yy < n){if(p[xx][yy] == '#' && !st[xx][yy]){st[xx][yy] = true;q.push({xx,yy});}if(p[xx][yy] == '.') flag = true;}}if(!flag) f[cnt] = true;}return;}int main(){cin >> n;for(int i = 0;i < n;++i) cin >> p[i];for(int i = 0;i < n; ++i){for(int j = 0;j < n; ++j){if(p[i][j] == '#' && !st[i][j]) bfs(i,j);}}int ans = 0;for(int i = 1;i <= cnt;++i){if(!f[i]) ans ++;}cout << ans << endl;}
5.八数码(2)
和上面那道八数码一样,不过是求到达最终态的方案
bfs + 状态转移
y总的代码耗时106ms
我图方便,在上一道八数码的代码修改了下,耗时3601ms
后面得拜读一下别人的代码
主要思想:想清楚:dx[i] , dy[i] 和 pos[i] 的对应关系,我第一次交这里就错了
#include<iostream>
#include<queue>
#include<cstring>using namespace std;const int N = 1e6 + 3;typedef long long LL;LL h[N];string ans[N];int dx[4] = {1, 0, -1, 0},dy[4] = {0, -1, 0, 1};char op[4] = {'d', 'l', 'u', 'r'};LL query_k(string s){LL t = 0;for(int i = 0;i < s.size(); ++i) t = t * 10 + s[i] - '0';return t;}int find(string s){LL t = query_k(s);int k = (t % N + N) % N;while(h[k] != -1 && h[k] != t){k++;if(k >= N) k = 0;}return k;
}bool bfs(string first){string end = "123456789";queue<string>q;q.push(first);h[find(first)] = query_k(first); while(q.size() != 0){int old_k,new_k;auto t = q.front();q.pop();old_k = find(t);if(t == end){cout << ans[old_k];return true;}int id = t.find('9');int x = id / 3,y = id % 3; for(int i = 0; i < 4; ++i){int xx = x + dx[i];int yy = y + dy[i];if(xx >= 0 && xx < 3 && yy >= 0 && yy < 3){swap(t[xx * 3 + yy],t[id]);new_k = find(t);if(h[new_k] == -1){q.push(t);h[new_k] = query_k(t);ans[new_k] = ans[old_k] + op[i];}swap(t[xx * 3 + yy],t[id]);}}}return false;
}int main(){memset(h,-1,sizeof(h));string first;for(int i = 1;i <= 9;++i){char c;cin >> c;if(c == 'x') first += '9';else first += c;}if(!bfs(first)) cout << "unsolvable" << endl;return 0;}
6.木棍
乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过 50个长度单位。
然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。
请你设计一个程序,帮助乔治计算木棒的可能最小长度。
每一节木棍的长度都用大于零的整数表示。
dfs + 剪枝
剪枝方案:
(1)优化搜索序列:优先选择较长的木棍,这样后面穷举的木棍数量就会变少
(2)排除等效冗余:要求先后加入的木棍有单调性,因为先来一根长度为x的木棍,再来一个长度为y的木棍,其实他们反过来是一样的,既然如此当然要有单调性.(在凑len长木棍时让编号从小到大放置,避免重复判断)
(3)排除等效冗余:对于当前木棍,记录最近一次尝试拼接失败的木棍,因为它失败了,那么肯定之后不能尝试再次凭借和他长度一模一样的木棍.因为他们是一模一样,没有任何差别,那么A死了,后面的A自然也得死,虽然他们下标不一样.
(4)排除等效冗余:如果第一次尝试拼入木棍就失败的话,那么这个分治必然也是失败的,因为在拼入这些木棍前,面对的原始木棍都是还没有拼接的,他们都是等效的.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>using namespace std;const int N = 100;int p[N];
bool st[N];
int n;
int sum,len;bool cmp(int a,int b){return a > b;
}bool dfs(int pos,int cur,int start){if(pos * len == sum) return true;if(cur == len) return dfs(pos + 1, 0, 1);for(int i = start;i <= n; ++i){if(st[i]) continue;if(cur + p[i] <= len){st[i] = true;if(dfs(pos,cur + p[i],i + 1)) return true;st[i] = false;} if(!cur||cur + p[i] == len) return false;int j = i + 1;while(p[i] == p[j] && j <= n) j++;i = j - 1;}return false;}int main(){while(cin >> n,n){sum = 0,len = 0;for(int i = 1; i <= n; ++i){cin >> p[i];sum += p[i];len = max(p[i],len);}sort(p + 1,p + n + 1,cmp);memset(st,0,sizeof(st));while(true){if(sum % len == 0 && dfs(0,0,1)){cout << len << endl;break;}len ++;}}return 0;}
相关文章:
蓝桥杯C++大学B组一个月冲刺记录2024/3/18
蓝桥杯C大学B组一个月冲刺记录2024/3/18 规则:每日三题 昨天因为前妻姐emo上了,静下来思考了点东西,就没做题啦.今日补上! 另外:博客浏览量破万了,写的东西有人看还是很开心的 1.母亲的牛奶 农夫约翰有三个容量分别为 A,B,C升的挤奶桶。 最开始桶 A和桶 B都是空的,…...
科技云报道:第五次工业革命,中国AI企业如何打造新质生产力?
科技云报道原创。 人类历史的叙述与技术进步的影响深深交织在一起。 迄今为止,每一次工业革命都彻底改变了我们社会的轮廓,引入了机械化、大规模生产和数字化,并重新定义了人类生存的规范。 自2022年11月30日OpenAI发布ChatGPT以来&#x…...
图片怎么转jpg格式?一键完成图片格式转换
jpg图片格式作为最常用的图片类型之一,经常出现在不同的使用场景中,如果遇到手上的图片不是jpg格式的话,就需要图片转jpg之后再操作,那么该如何进行图片转换格式呢?试试本文分享的这个图片转格式的方法吧,利…...
Qt笔记 信号和槽
在Qt中,如何将两个对象进行关联,让一个对象发出信号,然后另外一个对象接收到信号后,执行该对象的一个方法,要实现这种方式,则需要使用到信号和槽机制。 信号: 信号一定是一个没有返回值的函数…...
后端配置拦截器的一个问题【问题】
后端配置拦截器的一个问题【问题】 前言版权后端配置拦截器的一个问题问题解决 最后 前言 2024-3-14 00:07:28 以下内容源自《【问题】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是https://jsss-1.blog…...
C++提高笔记(六)---STL函数对象、STL常用算法(遍历、查找)
1、STL-函数对象 1.1函数对象 1.1.1函数对象概念 概念: 重载函数调用操作符的类,其对象常称为函数对象 函数对象使用重载的()时,行为类似函数调用,也叫仿函数 本质:函数对象(仿函数)是一个类,不是一个…...
【每日一问】手机如何开启USB调试?
一、背景 当电脑跟手机之间需要进行交互的时候,可以考虑使用usb进行连接。那么手机如何开启USB调试呢? 二、操作步骤: 思路: 步骤1:手机开启开发者模式 步骤2:在开发者模式中,开启“USB调试”…...
Java映射知识点(含面试大厂题含源码)
在Java中,映射(Map)是一个存储键值对的数据结构,其中每个键映射到一个值。Java提供了几种实现Map接口的类,以满足不同的需求。了解映射的知识点可以帮助你在处理需要键值关联的数据时更加高效。 核心知识点 Map接口&a…...
拆解Spring boot:Springboot为什么如此丝滑而简单?源码剖析解读自动装配
🎉🎉欢迎光临,终于等到你啦🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟持续更新的专栏《Spring 狂野之旅:从入门到入魔》 &a…...
中国银行信息系统应用架构发展历程
概述: 从 20 世纪 80 年代开始至今,我国银行业信息化历程已 有四十年历史。虽然相对于发达国家来讲,我国银行业务信 息化起步较晚,但发展速度很快, 目前我国一些大型商业银行的信息化程度已经处于全球领先水平。 “银行…...
掌握Go语言:探索Go语言指针,解锁高效内存操作与动态数据结构的奥秘(19)
指针是一个变量,它存储了另一个变量的地址。在Go语言中,指针提供了直接访问内存地址的能力,允许程序直接操作内存,这在某些场景下非常有用。 Go语言指针的详细使用方法 声明指针 可以使用*符号来声明指针变量,例如&…...
大数据面试题 —— Zookeeper
目录 ZooKeeper 的定义ZooKeeper 的特点ZooKeeper 的应用场景你觉得Zookeeper比较重要的功能ZooKeeper 的选举机制 ***zookeeper主节点故障,如何重新选举?ZooKeeper 的监听原理 ***zookeeper集群的节点数为什么建议奇数台 ***ZooKeeper 的部署方式有哪几…...
【安全类书籍-6】僵尸网络:网络程序杀手
目录 内容 用处 下载链接 内容 这本书着重探讨以下几个主题: 1. 僵尸网络基础:介绍僵尸网络的基本构成、运作机制以及在全球网络空间中的影响和威胁程度。 2. 僵尸网络技术剖析:详细分析僵尸网络的组件,如命令控制中心(C&C)、恶意软件传播途径、感染节点的招募和…...
文件的创建与删除
文件的创建 使用File类创建一个文件对象,例如:File filenew File("c:\\myletter" , "letter.txt"); public boolean createNewFile();/*如果c:\myletter目录中没 有名字为letter.txt文件,文件对象file调用createNewFil…...
图论题目集一(代码 注解)
目录 题目一: 题目二: 题目三: 题目四: 题目五: 题目六: 题目七: 题目一: #include<iostream> #include<queue> #include<cstring> using namespace st…...
解释MVC和MVVM架构模式
一、解释MVC和MVVM架构模式 MVC和MVVM都是常见的前端架构模式,用于抽象分离并解决特定问题。这两种模式在结构上具有一定的相似性,但在细节和数据处理方式上存在一些差异。 MVC,即Model-View-Controller,是一种用于应用程序分层…...
OLLAMA:如何像云端一样运行本地大语言模型
简介:揭开 OLLAMA 本地大语言模型的神秘面纱 您是否曾发现自己被云端语言模型的网络所缠绕,渴望获得更本地化、更具成本效益的解决方案?那么,您的探索到此结束。欢迎来到 OLLAMA 的世界,这个平台将彻底改变我们与大型…...
React全家桶及原理解析-lesson4-Redux
lesson4-react全家桶及原理解析.mov React全家桶及原理解析 React全家桶及原理解析 课堂⽬标资源起步Reducer 什么是reducer什么是reduceRedux 上⼿ 安装reduxredux上⼿检查点react-redux 异步代码抽取Redux拓展 redux原理 核⼼实现中间件实现redux-thunk原理react-redux原理 实…...
电商api数据接口技术开发来赞达lazada通过商品ID抓取商品详情信息item_get请求key接入演示
要获取Lazada的商品详情,你需要使用item_get请求。首先,你需要注册一个开发者账号并获取API密钥(App Key和App Secret)。然后,你可以使用以下Python代码示例来获取商品详情: # coding:utf-8 ""&…...
零基础入门多媒体音频(2)-音频焦点2
说实话,android的代码是越来越难以阅读。业务函数里面狗皮膏药似的补丁与日俱增。继上篇简要介绍音频焦点的文章,这篇文章的主要内容是分析audiofocus的实现。看了一下午的相关代码都没找到做audiofocus策略的核心逻辑。目前能看懂的大概包含下面两个逻辑…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
Xcode 16 集成 cocoapods 报错
基于 Xcode 16 新建工程项目,集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...
医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor
1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...
