第十四届蓝桥杯大赛软件赛国赛C/C++ 大学 B 组(部分题解)

2024-05-12 13:36

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

文章目录

  • 1 子2023
    • 思路:
    • 代码:
  • 2 双子数
    • 思路:
    • 代码:
  • 3 班级活动
    • 思路:
    • 代码:
  • 4 合并数列
    • 思路:
    • 代码:
  • 5 数三角
    • 思路:
    • 代码:
  • 7 AB路线
    • 思路:
    • 代码:
  • 8 抓娃娃
    • 思路:
    • 代码:


1 子2023

思路:

  • 比较基础的线性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
#define fi first
#define se second
#pragma GCC optimize(2)
#pragma GCC optimize("inline")
typedef pair<int,int> PII;
const int N = 1e3+10, INF = 0x3f3f3f3f;
int n=2023,ans;
string s="";
int dp[3];
//dp[0]:当前位置之前"2"的个数
//dp[1]:当前位置之前"20"的个数
//dp[2]:当前位置之前:"202"的个数 void solve(){for(int i=1;i<=n;i++) s+=to_string(i);for(int i=0;i<s.size();i++){if(s[i]=='2') dp[0]++,dp[2]+=dp[1]; //2,202else if(s[i]=='0') dp[1]+=dp[0];//20else if(s[i]=='3') ans+=dp[2];//202加上当前位置的3 } cout<<ans; //5484660609
}signed main(){int T=1;
//	IOS;
//	cin>>T;while(T--){solve();} return 0;
}

2 双子数

思路:

  • 欧拉筛求素数,然后枚举所有素数,找到满足条件的
  • 记得超出范围时要及时break,不然会爆long long

代码:

#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 = 5e6+10, INF = 0x3f3f3f3f;
int L=2333,R=23333333333333; 
int ans;
int prime[N],cnt;
bool isprime[N];
set<int> s;void get_prime(){memset(isprime,1,sizeof(isprime));isprime[1]=0;for(int i=2;i<N;i++){if(isprime[i]) prime[++cnt]=i;for(int j=1;j<=cnt&&i*prime[j]<N;j++){isprime[i*prime[j]]=0;if(i%prime[j]==0) break;}}
}void solve(){get_prime();for(int i=1;i<=cnt;i++){int res=prime[i]*prime[i]*prime[i+1]*prime[i+1];if(res>R) break; //及时break,不然会溢出long long!!!for(int j=i+1;j<=cnt;j++){int res=prime[i]*prime[i]*prime[j]*prime[j];if(res>=L&&res<=R) ans++;if(res>R) break;}}cout<<ans; //947293
}signed main(){int T=1;
//	IOS;
//	cin>>T;while(T--){solve();} return 0;
}

3 班级活动

思路:

  • 认真读题,题目中说了“有且仅有一名同学”,也是就是说两两相同,每对数之间是不同的
  • 所以id个数大于2的部分都是要修改的,根据贪心的思想,我们更希望把这些多出的部分和单个的id来配对!
  • 所以分为两类,多出的部分sum1,和单个的sum2,比较那个大
  • sum1>=sum2,把多出的部分修改为和单个的id相同的id,然后把剩下的sum1全都修改
  • sum1<sum2,就把多出的部分修改为和单个的id相同的id,然后把剩下的sum2修改一半即可!

代码:

#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 = 1e5+10, INF = 0x3f3f3f3f;
int n,a[N],ans; void solve(){cin>>n;map<int,int> mp;for(int i=1;i<=n;i++){cin>>a[i];mp[a[i]]++;}int sum1=0,sum2=0,ans=0;for(auto i:mp){if(i.se>2) sum1+=i.se-2; //多出的else if(i.se<2) sum2++; //单个的}if(sum1>=sum2) sum1-=sum2,ans+=sum2+sum1;else sum2-=sum1,ans+=sum1,ans+=sum2/2;cout<<ans;
}signed main(){int T=1;
//	IOS;
//	cin>>T;while(T--){solve();} return 0;
}

4 合并数列

思路:

  • 双指针,分别指向两个数组开头
  • 比较哪个大,小的那个就和后边的合并
  • 相等的话都同时右移

代码:

#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 = 1e5+10, INF = 0x3f3f3f3f;
int n,m,a[N],b[N];void solve(){cin>>n>>m;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=m;i++) cin>>b[i];int cnt=0;int i=1,j=1,k1=1,k2=1;while(i<=n||j<=m){
//		cout<<i<<' '<<j<<' '<<a[i]<<' '<<b[j]<<endl;if(a[i]==b[j]){i+=k1; j+=k2;k1=1; k2=1;}else if(a[i]>b[j]){b[j]+=b[j+k2]; ++k2; ++cnt;}else{a[i]+=a[i+k1]; ++k1; ++cnt;}}cout<<cnt;
}signed main(){int T=1;
//	IOS;
//	cin>>T;while(T--){solve();} return 0;
}

5 数三角

思路:

  • 以每个点为顶点,找出到顶点距离相等的点的集合,然后遍历这些点,满足条件答案加1,当然这里的满足条件指的是三点不共线
  • 用斜率来判断三点是否共线

代码:

#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 = 1e5+10, INF = 0x3f3f3f3f;
int n,ans;
vector<PII> arr;double get_dist(int x1,int y1,int x2,int y2){ //两点间距离 return pow(x1-x2,2)+pow(y1-y2,2);
}bool check(PII p1,PII p2,PII p3){if(p1.fi==p2.fi&&p1.fi==p3.fi) return true; //共线 double k1=(p1.se-p2.se)*1.0/(p1.fi-p2.fi);double k2=(p1.se-p3.se)*1.0/(p1.fi-p3.fi);return k1==k2; //斜率相等,共线 
}void solve(){cin>>n;for(int i=0;i<n;i++){int x,y; cin>>x>>y;arr.push_back({x,y}); //记录坐标 } for(int i=0;i<n;i++){map<int,vector<int>> mp; //存储到i号点距离相等的点的集合 for(int j=0;j<n;j++){if(i!=j){PII p1=arr[i],p2=arr[j];double d=get_dist(p1.fi,p1.se,p2.fi,p2.se);mp[d].push_back(j);}}for(auto t:mp){ //遍历所有的距离 vector<int> v=t.se; //到i号点距离相等的点 for(int j=0;j<v.size();j++){for(int k=j+1;k<v.size();k++){if(!check(arr[i],arr[v[j]],arr[v[k]])) ++ans;}}}}cout<<ans;
}signed main(){int T=1;
//	IOS;
//	cin>>T;while(T--){solve();} return 0;
}

7 AB路线

思路:

  • bfs,每个点可以走多次

代码:

#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;
int n,m,k,ans=-1;
char g[N][N];
bool st[N][N][11];
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
struct node{int x,y,num,step;
};void bfs(){queue<node> q;q.push({0,0,1,0});st[0][0][1]=1;while(q.size()){auto t=q.front(); q.pop();int x=t.x,y=t.y,num=t.num,step=t.step;if(x==n-1&&y==m-1){ans=step;break;}for(int i=0;i<4;i++){int tx=x+dx[i],ty=y+dy[i];if(tx<0||ty<0||tx>=n||ty>=m) continue;if(num==k){if(g[x][y]==g[tx][ty]||st[tx][ty][1]) continue;st[tx][ty][1]=1;q.push({tx,ty,1,step+1});}else if(g[tx][ty]==g[x][y]){if(st[tx][ty][num+1]) continue;st[tx][ty][num+1]=1;q.push({tx,ty,num+1,step+1});}}}}void solve(){cin>>n>>m>>k;for(int i=0;i<n;i++){for(int j=0;j<m;j++){cin>>g[i][j];}}bfs();cout<<ans;
}signed main(){int T=1;
//	IOS;
//	cin>>T;while(T--){solve();} return 0;
}

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 = 1e5+10, INF = 0x3f3f3f3f;
int n,m;
int a[N][2],b[N];void solve(){cin>>n>>m;for(int i=1;i<=n;i++){int l,r; cin>>l>>r;l<<=1; r<<=1;a[i][0]=l,a[i][1]=r;b[i]=l+r>>1; //获取该线段中点 }sort(b+1,b+1+n);for(int i=1;i<=m;i++){int l,r; cin>>l>>r;l<<=1; r<<=1;int pos1=lower_bound(b+1,b+1+n,l)-b;int pos2=upper_bound(b+1,b+1+n,r)-b;cout<<pos2-pos1<<endl;} 
}signed main(){int T=1;
//	IOS;
//	cin>>T;while(T--){solve();} return 0;
}

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



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

相关文章

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

C++11委托构造函数和继承构造函数的实现

《C++11委托构造函数和继承构造函数的实现》C++引入了委托构造函数和继承构造函数这两个重要的特性,本文主要介绍了C++11委托构造函数和继承构造函数的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、委托构造函数1.1 委托构造函数的定义与作用1.2 委托构造函数的语法1.3 委托构造函

C++11作用域枚举(Scoped Enums)的实现示例

《C++11作用域枚举(ScopedEnums)的实现示例》枚举类型是一种非常实用的工具,C++11标准引入了作用域枚举,也称为强类型枚举,本文主要介绍了C++11作用域枚举(ScopedEnums... 目录一、引言二、传统枚举类型的局限性2.1 命名空间污染2.2 整型提升问题2.3 类型转换问题三、C

C++链表的虚拟头节点实现细节及注意事项

《C++链表的虚拟头节点实现细节及注意事项》虚拟头节点是链表操作中极为实用的设计技巧,它通过在链表真实头部前添加一个特殊节点,有效简化边界条件处理,:本文主要介绍C++链表的虚拟头节点实现细节及注... 目录C++链表虚拟头节点(Dummy Head)一、虚拟头节点的本质与核心作用1. 定义2. 核心价值二

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

Qt 设置软件版本信息的实现

《Qt设置软件版本信息的实现》本文介绍了Qt项目中设置版本信息的三种常用方法,包括.pro文件和version.rc配置、CMakeLists.txt与version.h.in结合,具有一定的参考... 目录在运行程序期间设置版本信息可以参考VS在 QT 中设置软件版本信息的几种方法方法一:通过 .pro