第十四届蓝桥杯c++b组

2024-04-12 22:12
文章标签 c++ 蓝桥 第十四届

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

1.日期统计

前四位已经固定,四重循环暴力生成后四位,并将合法的日期记录下来,然后检验这些日期能否被生成

具体如何检验:

由于题目说的是子序列,所以可以跳着选,但是相对顺序是不能变的,所以对于给定的100个数,从前往后一位一位和日期的8位匹配,如果一位匹配成功就匹配下一位,如果日期的8位都匹配成功了,那么就说明该日期合法

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
int mon[13]={-1,31,29,31,30,31,30,31,31,30,31,30,31};
void solve() {set<int>s;int a[100]={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};for(int i=0;i<=9;i++){for(int j=0;j<=9;j++){for(int k=0;k<=9;k++){for(int m=0;m<=9;m++){int tmp=2023;tmp=tmp*10+i;tmp=tmp*10+j;tmp=tmp*10+k;tmp=tmp*10+m;string x=to_string(tmp);int month=(x[4]-'0')*10+x[5]-'0';int day=(x[6]-'0')*10+x[7]-'0';if(month>=1&&month<=12&&day>=1&&day<=mon[month]) s.insert(tmp);}}}}int ans=0;for(auto v:s){string t=to_string(v);int cnt=0;for(int i=0;i<100;i++){if(a[i]==t[cnt]-'0') cnt++;}if(cnt==(int)t.size()) ans++;}cout<<ans<<endl;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;
//    cin>>t;while(t--) {solve();}return 0;
}

2.01串的熵

就是很简单的式子,枚举0的个数和1的个数,检验能否满足给定式子

#include<bits/stdc++.h>
#define endl '\n'
#define eps 1e-4
#define int long long
using namespace std;
void solve() {for(int i=0;i<=23333333;i++){//枚举0的个数int j=23333333-i;//1的个数if(i>j) break;double p0=(double)i/23333333;//0的占比double p1=(double)j/23333333;//1的占比double sum0=(-1)*i*p0*log2(p0);double sum1=(-1)*j*p1*log2(p1);double sum=sum0+sum1;if(abs(sum-11625907.5798)<eps){cout<<i<<endl;return;}}
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;
//    cin>>t;while(t--) {solve();}return 0;
}

3.冶炼金属

法一:

找一下规律,比如题目中的样例

3
75 3
53 2
59 2
75/3=25
75/4=1875/25=3
75/24=3
75/23=3
...
75/19=3
75/18=4
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=1e4+10;
int a[N],b[N];
int n;
void solve() {cin>>n;for(int i=1;i<=n;i++) cin>>a[i]>>b[i];int maxn=2e9,minn=0;for(int i=1;i<=n;i++){int u=a[i]/b[i];int v=a[i]/(b[i]+1)+1;maxn=min(maxn,u);minn=max(minn,v);}cout<<minn<<' '<<maxn<<endl;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;
//    cin>>t;while(t--) {solve();}return 0;
}

法二:二分答案

在[1,1e9]二分出一个答案

如果是求最小的转换率,那么对于每个答案,check每条记录是否满足产出均小于等于b[i],如果是返回true,找到最小的返回为true的转换率

产出的均小于等于b,需要找到最小的x满足产出均等于b[i],一定存在,因为题目说一定有解

求最大的转换率同理

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=1e4+10;
int a[N],b[N];
int n;
bool check1(int x){for(int i=1;i<=n;i++){if(a[i]/x>b[i]) return false;}return true;//产出的均小于等于b,需要找到最小的x满足产出均等于b[i],一定存在,因为题目说一定有解
}
bool check2(int x){for(int i=1;i<=n;i++){if(a[i]/x<b[i]) return false;}return true;//产出的均大于等于b,需要找到最大的x满足产出均等于b[i],一定存在,因为题目说一定有解
}
void solve() {cin>>n;for(int i=1;i<=n;i++) cin>>a[i]>>b[i];int l=1,r=1e9;while(l<r){int mid=(l+r)>>1;if(check1(mid)) r=mid;else l=mid+1;}int minn=l;l=1,r=1e9;while(l<r){int mid=(l+r+1)>>1;if(check2(mid)) l=mid;else r=mid-1;}int maxn=l;cout<<minn<<' '<<maxn<<endl;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;
//    cin>>t;while(t--) {solve();}return 0;
}

4.飞机降落

数据很小,直接暴力枚举每种情况,并check是否至少一种情况可以使得飞机成功降落

全排列即可

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=15;
int t[N],d[N],l[N];
int a[N];
int n;
void solve() {cin>>n;for(int i=1;i<=n;i++) cin>>t[i]>>d[i]>>l[i],a[i]=i;do{bool ok=true;int ed=0;//上一架飞机降落结束时间for(int i=1;i<=n;i++){if(t[a[i]]+d[a[i]]<ed){ok=false;break;}int st=max(ed,t[a[i]]);//开始降落时间ed=st+l[a[i]];}if(ok){cout<<"YES"<<endl;return;}}while(next_permutation(a+1,a+1+n));cout<<"NO"<<endl;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;cin>>t;while(t--) {solve();}return 0;
}

5.接龙数列

问最少删除几个,也就是说最多保留几个

其实可以先求最长接龙子序列的长度,再用总长度减去它

从前往后枚举每个数,当以这个数作为接龙子序列的结尾时,它前面一个数的尾必须是它的头,所以dp[尾]=max(dp[尾],dp[头]+1)

dp[x]表示x作为尾的接龙子序列的最长长度

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=1e5+10;
int dp[N];
int n;
void solve() {cin>>n;int ans=0;for(int i=1;i<=n;i++){string s;cin>>s;int len=s.size()-1;int x=s[0]-'0';int y=s[len-1]-'0';dp[y]=max(dp[y],dp[x]+1);ans=max(ans,dp[y]);}cout<<n-ans<<endl;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;
//    cin>>t;while(t--) {solve();}return 0;
}

6.岛屿个数

和外海接触的岛屿肯定不是子岛屿

先将外围一圈标记为外海,从(0,0)开始搜,将所有的外海搜出来(8方向),标记为2

然后对于那些内海,仍为0,将它们都标记为陆地

最后搜陆地一共有几个连通块即可

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
typedef pair<int,int>PII;
const int N=55;
char s[N][N];
int m,n;
int dx1[8]={0,0,1,-1,1,1,-1,-1},dy1[8]={1,-1,0,0,-1,1,-1,1};
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
void dfs1(int x,int y){//找和外海相连的海,将所有外海标记为2s[x][y]='2';for(int i=0;i<8;i++){int tx=x+dx1[i],ty=y+dy1[i];if(tx<0||tx>m+1||ty<0||ty>n+1||s[tx][ty]!='0') continue;dfs1(tx,ty);}
}
void dfs2(int x,int y){//对于找到的所有外海,去找和外海接壤的陆地s[x][y]='3';for(int i=0;i<4;i++){int tx=x+dx[i],ty=y+dy[i];if(tx<0||tx>m+1||ty<0||ty>n+1||s[tx][ty]!='1') continue;dfs2(tx,ty);}
}
void solve() {cin>>m>>n;for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){cin>>s[i][j];}}//外海一圈,朝8个方向搜,搜到所有的外海for(int i=0;i<=m+1;i++){for(int j=0;j<=n+1;j++){if(s[i][j]=='1'||s[i][j]=='0') continue;s[i][j]='0';}}dfs1(0,0);for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(s[i][j]=='0') s[i][j]='1';//将内海变成陆地}}int ans=0;for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){if(s[i][j]=='1'){dfs2(i,j);ans++;}}}cout<<ans<<endl;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;cin>>t;while(t--) {solve();}return 0;
}

7.子串简写

将字符为c1的位置都存储下来,然后枚举到字符为c2时,二分到最大的满足以c2结尾,c1开头的长度大于等于k的位置,然后该位置以及前面的c1都满足,作为对答案的贡献

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
int k;
string s;
char c1,c2;
void solve() {cin>>k;cin>>s;cin>>c1>>c2;map<char,int>mp;vector<int>a;int ans=0;for(int i=0;i<(int)s.size();i++){if(s[i]==c1) a.push_back(i);else if(s[i]==c2){if(!a.size()) continue;int l=0,r=a.size()-1;while(l<r){int mid=(l+r+1)>>1;if(i-a[mid]+1>=k) l=mid;else r=mid-1;}if(i-a[l]+1>=k) ans+=l+1;}}cout<<ans<<endl;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;
//    cin>>t;while(t--) {solve();}return 0;
}

8.整数删除

线性存储结构进行删除操作时间复杂度为O(n),使用链式存储结构更适合

用双链表,这里用数组模拟

利用优先队列(小根堆),方便取出值最小的元素

这里我们删除一个元素时,需要将它左右两边的元素都加上它的值,但是我们无法在优先队列随意修改元素,所以这里有一个技巧,先记录下来下标为x的元素更新后的值,先不急着更新优先队列,类似于线段树的懒标记,等到用到了才更新优先队列,当队头的值是最新的值的时候,那么说明更新过了,那么执行删除操作,否则,需要在优先队列中更新它的值

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
typedef pair<int,int>PII;
const int N=5e5+10;
int a[N];
int l[N],r[N];//用数组模拟双链表
int n,k;
void del(int x){l[r[x]]=l[x],r[l[x]]=r[x];a[l[x]]+=a[x],a[r[x]]+=a[x];
}
void solve() {cin>>n>>k;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=n;i++) l[i]=i-1;r[0]=1;for(int i=n;i>=1;i--) r[i]=i+1;priority_queue<PII,vector<PII>,greater<PII>>q;for(int i=1;i<=n;i++) q.push({a[i],i});while(k--){auto t=q.top();q.pop();if(t.first!=a[t.second]){q.push({a[t.second],t.second});k++;}else del(t.second);}for(int i=r[0];i<=n;i=r[i]) cout<<a[i]<<' ';cout<<endl;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t=1;
//    cin>>t;while(t--) {solve();}return 0;
}

这篇关于第十四届蓝桥杯c++b组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

使用C/C++调用libcurl调试消息的方式

《使用C/C++调用libcurl调试消息的方式》在使用C/C++调用libcurl进行HTTP请求时,有时我们需要查看请求的/应答消息的内容(包括请求头和请求体)以方便调试,libcurl提供了多种... 目录1. libcurl 调试工具简介2. 输出请求消息使用 CURLOPT_VERBOSE使用 C

C++实现获取本机MAC地址与IP地址

《C++实现获取本机MAC地址与IP地址》这篇文章主要为大家详细介绍了C++实现获取本机MAC地址与IP地址的两种方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实际工作中,项目上常常需要获取本机的IP地址和MAC地址,在此使用两种方案获取1.MFC中获取IP和MAC地址获取

C/C++通过IP获取局域网网卡MAC地址

《C/C++通过IP获取局域网网卡MAC地址》这篇文章主要为大家详细介绍了C++如何通过Win32API函数SendARP从IP地址获取局域网内网卡的MAC地址,感兴趣的小伙伴可以跟随小编一起学习一下... C/C++通过IP获取局域网网卡MAC地址通过win32 SendARP获取MAC地址代码#i