第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(补题)

2024-03-28 14:44

本文主要是介绍第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(补题),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 1 日期统计
    • 2 01串的熵
    • 3 冶炼金属
    • 4 飞机降落
    • 5 接龙数列
    • 6 岛屿个数
    • 7 子串简写
    • 8 整数删除
    • 9 景区导游
    • 10 砍树


前言:时隔一年,再次做这套题(去年参赛选手),差点道心不稳T_T,故作此补题!

1 日期统计

  • 没写出来,看题解知道了一种暴力的思想,枚举所有2023年的日期,看看有没有满足条件的数。
  • 关于如何提取题中的数字?可以复制到excel当中,然后ctrl+H,将空格替换为英文逗号!
#include<bits/stdc++.h>
using namespace std;#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
typedef pair<int,int> PII;
const int N = 2e5+10, INF = 0x3f3f3f3f;
int a[N]={0,5,6,8,6,9,1,6,1,2,4,9,1,9,8,2,3,6,4,7,7,5,9,5,0,3,8,7,5,8,1,5,8,6,1,8,3,0,3,7,9,2,7,0,5,8,8,5,7,0,9,9,1,9,4,4,6,8,6,3,3,8,5,1,6,3,4,6,7,0,7,8,2,7,6,8,9,5,6,5,6,1,4,0,1,0,0,9,4,8,0,9,1,2,8,5,0,2,5,3,3};
int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int n=100,ans;void solve() {for(int m=1;m<=12;m++) //枚举所有日期for(int d=1;d<=mon[m];d++){int tar[9]={0,2,0,2,3,m/10,m%10,d/10,d%10}; //当前日期int num=1;for(int i=1;i<=100;i++){ //看看有没有符合条件的if(a[i]==tar[num]){num++;if(num==9){ans++; break;}}}}cout<<ans;
}signed main() {
//	IOS;int T=1;
//	cin>>T;while(T--) {solve();}return 0;    
}

2 01串的熵

  • 因为0的出现次数比1的出现次数少,所以我们可以枚举0的个数,1的个数即为01串的长度减去0的个数。
  • 然后根据公式即可求得
#include<bits/stdc++.h>
using namespace std;#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
const int N = 2e5+10, INF = 0x3f3f3f3f;
int len=23333333,cnt;
double res,tar=11625907.5798; void solve() {for(int i=0;i<=len;i++){ //0的数量 int j=len-i; //1的数量 res=-1.0*(1.0*i/len)*i*(log(1.0*i/len)/log(2))+(-1)*(1.0*j/len)*j*(log(1.0*j/len)/log(2));if(res>=tar){printf("%.4f %.4f\n",res,tar);cout<<i<<endl; break;}}}signed main() {
//	IOS;int T=1;
//	cin>>T;while(T--) {solve();}return 0;    
}

3 冶炼金属

  • 读完题目后,我们可以枚举答案来求得V的最大值和最小值,即用到二分答案。
#include<bits/stdc++.h>
using namespace std;#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
const int N = 1e4+10, INF = 0x3f3f3f3f;
int n,a[N],b[N];
int res1,res2;bool check1(int x){for(int i=1;i<=n;i++){int num=a[i]/x; //转换的个数if(num>b[i]) return false;}return true;
}int calc1(){int l=0,r=1e9+10;while(l+1<r){int mid=l+r>>1;if(check1(mid)) r=mid; //满足条件,缩小范围求最小值else l=mid;}return r;
}bool check2(int x){for(int i=1;i<=n;i++){int num=a[i]/x;if(num<b[i]) return false;}return true;
}int calc2(){int l=0,r=1e9+10;while(l+1<r){int mid=l+r>>1;if(check2(mid)) l=mid;else r=mid;}return l;
}void solve() {cin>>n;for(int i=1;i<=n;i++)cin>>a[i]>>b[i];res1=calc1(); //最小值res2=calc2(); //最大值cout<<res1<<' '<<res2;
}signed main() {
//	IOS;int T=1;
//	cin>>T;while(T--) {solve();}return 0;    
}

4 飞机降落

  • N的数据范围只有10,我们可以暴力枚举所有飞机降落的顺序,如果有一个满足就符合要求。
  • 用全排列函数next_permutation函数可以实现这一操作
#include<bits/stdc++.h>
using namespace std;#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
const int N = 1e3+10, INF = 0x3f3f3f3f;
struct node{int t,d,l;
}a[N];
int n,id[N]; void solve() {cin>>n;for(int i=1;i<=n;i++){int t,d,l; cin>>t>>d>>l;a[i]={t,d,l}; id[i]=i;}do{int now=0,flag=1;for(int i=1;i<=n;i++){int t=a[id[i]].t,d=a[id[i]].d,l=a[id[i]].l;if(t+d<now){ //不符合flag=0;break;} else{if(t>now) now=t+l;else now+=l;}}if(flag){cout<<"YES"<<endl;return;}}while(next_permutation(id+1,id+1+n)); cout<<"NO"<<endl;
}signed main() {
//	IOS;int T=1;cin>>T;while(T--) {solve();}return 0;    
}

5 接龙数列

  • 可以将问题转化为求最长的符合要求的接龙序列,然后用总个数减去最长的接龙序列的长度。
  • 这就需要dp来解决了
#include<bits/stdc++.h>
using namespace std;#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
const int N = 1e5+10, INF = 0x3f3f3f3f;
int n,num=0;
int x,dp[N];
//dp[i]表示以i为结尾的最长接龙序列的长度 void solve(){cin>>n;string s;for(int i=0;i<n;i++){cin>>s;int x=s[0]-'0',y=s[s.size()-1]-'0'; //取出第一位和最后一位 dp[y]=max(dp[y],dp[x]+1);num=max(num,dp[y]);}cout<<n-num;
}signed main() {
//	IOS;int T=1;
//	cin>>T;while(T--) {solve();}return 0;    
}

6 岛屿个数

  • 连通块,图的遍历问题
  • 可以将所有的连通块染色,每一种颜色代表一个连通块。
  • 然后检查所有的岛屿是不是子岛屿,即该岛屿是否在“环”的内部,如何判断是否在环的内部呢?
  • 如果该岛屿内的任意一个点可以走到边界或边界之外,说明该岛屿不在环内,可以把其它的岛屿看作障碍物;如果在环内,则不可能到达边界点!
  • 判断是否为子岛屿时,需要沿着8个方向走!
#include<bits/stdc++.h>
using namespace std;#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define fi first
#define se second
typedef pair<int,int> PII;
const int N = 1e3+10, INF = 0x3f3f3f3f;
char g[N][N];
int m,n,cnt,ans;
int c[N][N]; 
int dx[]={0,1,0,-1,-1,1,1,-1};
int dy[]={1,0,-1,0,1,1,-1,-1};
set<int> s;void bfs(int sx,int sy){cnt++; //该连通块染色为cntqueue<PII> q;q.push({sx,sy});while(q.size()){auto t=q.front(); q.pop();c[t.fi][t.se]=cnt;for(int i=0;i<4;i++){int tx=t.fi+dx[i];int ty=t.se+dy[i];if(tx<=0||tx>m||ty<=0||ty>n) continue;if(c[tx][ty]||g[tx][ty]=='0') continue;q.push({tx,ty});}}
}bool vis[N][N],flag;
//判断是否在环内
bool check(int x,int y,int col){if(flag) return true;for(int i=0;i<8;i++){int tx=x+dx[i];int ty=y+dy[i];if(c[tx][ty]!=col&&c[tx][ty]) continue;
//		if(col==3) cout<<tx<<' '<<ty<<' '<<flag<<endl;if(tx<=1||ty<=1||tx>=m||ty>=n){ //到达边界,不在环内flag=1;return true;}if(vis[tx][ty]) continue; //已访问过vis[tx][ty]=1;if(check(tx,ty,col)) return true;}return false; //在环内
}void solve() {cin>>m>>n;for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)cin>>g[i][j];cnt=0; ans=0; s.clear(); //多组样例!注意清空!memset(c,0,sizeof(c));for(int i=1;i<=m;i++)for(int j=1;j<=n;j++){if(!c[i][j]&&g[i][j]=='1'){bfs(i,j);}}
//	cout<<endl;
//	for(int i=1;i<=m;i++){
//		for(int j=1;j<=n;j++)
//		  cout<<c[i][j];
//		cout<<endl;
//	}set<int> s; //set去重for(int i=1;i<=m;i++)for(int j=1;j<=n;j++){
//	  	cout<<i<<' '<<j<<' '<<c[i][j]<<endl;if(g[i][j]=='1'&&!s.count(c[i][j])&&check(i,j,c[i][j])){s.insert(c[i][j]);}memset(vis,0,sizeof(vis)); flag=0;}cout<<s.size()<<endl;
}signed main() {
//	IOS;int T=1;cin>>T;while(T--) {solve();}return 0;    
}

7 子串简写

  • 我们可以记录两个字符a,b的所有位置,然后枚举第一个字符a,二分找到第一个符合要求的字符b的位置,之后所有的字符b都是符合要求的,累加所有答案即可
  • 复杂度为O(n log(n))
#include<bits/stdc++.h>
using namespace std;#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define lb lower_bound
typedef pair<int,int> PII;
const int N = 2e5+10, INF = 0x3f3f3f3f;
int k,ans;
string s;
set<int> s1;
vector<int> a;
char c1,c2;void solve() {
//	freopen("in.txt","r",stdin); cin>>k>>s>>c1>>c2;for(int i=0;i<s.size();i++){if(s[i]==c1) s1.insert(i); //保存所有位置if(s[i]==c2) a.push_back(i);}for(auto i:s1){int cnt=lb(a.begin(),a.end(),i+k-1)-a.begin(); //二分查找ans+=a.size()-cnt;}
//	freopen("out.txt","w",stdout); cout<<ans;
}signed main() {
//	IOS;int T=1;
//	cin>>T;while(T--) {solve();}return 0;    
}

8 整数删除

  • 优先队列+链表
  • 每次取出数列中的最小值,可以用优先队列实现。
  • 删除和相邻两数加上被删除的值这两个操作用链表来实现。
  • 代码见蓝桥发题解的大佬

9 景区导游

  • 不会T_T
  • 用LCA来求解

10 砍树

  • 树上差分模板题

这篇关于第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(补题)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/855898

相关文章

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

Ubuntu 怎么启用 Universe 和 Multiverse 软件源?

《Ubuntu怎么启用Universe和Multiverse软件源?》在Ubuntu中,软件源是用于获取和安装软件的服务器,通过设置和管理软件源,您可以确保系统能够从可靠的来源获取最新的软件... Ubuntu 是一款广受认可且声誉良好的开源操作系统,允许用户通过其庞大的软件包来定制和增强计算体验。这些软件

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象