第十五届蓝桥杯省赛大学B组(c++)

news2024/12/23 20:29:57

很幸运拿了辽宁赛区的省一,进入6月1号的国赛啦...

这篇文章主要对第十五届省赛大学B组(C++)进行一次完整的复盘,这次省赛==2道填空题+6道编程题:

A.握手问题

把握手情景看成矩阵:

粉色部分是7个不能互相捂手的情况

由于每个人只能和其他人捂手, 所以黑色情况是不算的

1和2握手==2和1握手,就是只用算一半的对角矩阵

#include<iostream>
using namespace std;
int main(){
    int a=0;
    for(int i=49;i;i--) a+=i;
    int b=0;
    for(int i=6;i;i--) b+=i;
    int ans=a-b;
    cout<<ans<<endl;//最后求得答案为1204 
    return 0;
}

B.小球反弹

这题考试的时候我是直接跳过的,到最后也没来得及看,看了估计也算不对,haha

整体思路是:

最终返回左上角时,小球走过的水平路程和垂直路程一定是343720和233333的偶数倍

并且水平路程与垂直路程之比一定为15:17

#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e4;
const ll X=343720;
const ll Y=233333;
int main(){
    for(ll x=2;x<=N;x+=2){
        for(ll y=2;y<=N;y+=2){
            if (15*Y*y==17*X*x){
                printf("%lf",sqrt((X*x)*(X*x)+(Y*y)*(Y*y)));
                //结果是1100325199.770395
                return 0;
            }
        }
    }
}

C.好数

这题暴力枚举就能AC,数据不大,haha

#include<iostream>
using namespace std;
typedef long long ll;
const int N=1e7+5;
ll ans;
bool check(int x){
    int flag=0;
    while(x>0){
        int t=x%10;
        if(!flag){
            if(t%2==0) return false;
            else flag=1;
        }
        else{
            if(t%2!=0) return false;
            else flag=0;
        }
        x/=10;
    }
    return true;
}
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) if(check(i)) ans++;
    cout<<ans<<endl;
    return 0;
}

D.R格式

考试时候的代码:

#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
int main(){
    int n;
    double d;
    cin>>n>>d;
    ll a=(ll)pow(2,n);
    double ans=a*d;
    double res=(ll)ans+0.5;
    if(ans>=res) cout<<(ll)ans+1<<endl;
    else cout<<(ll)ans<<endl;
    return 0;
}

混了一半的分数:

高精度优化(AC): 

#include<iostream>
#include<algorithm>//reverse函数:前后翻转
#include<cstring>//to_string函数:数字常量转化为字符串
using namespace std;
typedef long long ll;
int n;string d;
string ans="1";
string add(string a,string b){
    string res;
    int la=a.size(),lb=b.size();
    int i=la-1,j=lb-1,jw=0;
    while(i>=0||j>=0){
        int sum=jw;
        if(i>=0) sum+=a[i--]-'0';
        if(j>=0) sum+=b[j--]-'0';
        jw=sum/10;
        res+=to_string(sum%10);
    }
    if(jw) res+=to_string(jw);
    reverse(res.begin(),res.end());
    return res;
}
string mul(string a,string b){
    string res="0";
    int la=a.size(),lb=b.size();
    for(int i=la-1;i>=0;i--){
        int jw=0;
        string temp;
        for(int j=lb-1;j>=0;j--){
            int sum=(a[i]-'0')*(b[j]-'0')+jw;
            jw=sum/10;
            temp+=to_string(sum%10);
        }
        if(jw) temp+=to_string(jw);
        reverse(temp.begin(),temp.end());
        for(int k=0;k<la-1-i;k++) temp+="0";
        res=add(res,temp);
    }
    return res;
}
int main(){
    cin>>n>>d;
    while(n--) ans=mul(ans,"2");
    string newd="";int flag;
    for(int i=0;i<d.size();i++){
        if(d[i]!='.') newd+=d[i];
        else flag=d.size()-i-1;
    }
    ans=mul(newd,ans);
    int key=ans.size()-flag;
    string s="";
    for(int i=0;i<key;i++) s+=ans[i];
    if(ans[key]>='5') s=add(s,"1");
    cout<<s;
    return 0;
}

E.宝石组合

整体思路(当然考试时候我肯定是没想出来):

由最小公倍数和最大公约数的性质
我们可以推出S的值就等于三个数的最大公约数gcd(h[a],h[b],h[c])
当三个数的最大公约数最大时,s最大,然后把包含此因子的三个最小数输出即可
//最大公约数
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
//最小公倍数
int lcm(int a,int b){
    return a*b/gcd(a,b);
}

暴力:

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,h[N],ans[5],res[5],temp=0;
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
int gcd3(int a,int b,int c){
    return gcd(gcd(a,b),c);
}
void dfs(int x,int startt) {
    if(x>3){
        int y=gcd3(h[ans[1]],h[ans[2]],h[ans[3]]);
        if(y>temp){
            res[1]=ans[1],res[2]=ans[2],res[3]=ans[3];
            temp=y;
        }
        return ;
    }
    for(int i=startt;i<=n;i++){
        ans[x]=i;
        dfs(x+1,i+1);
        ans[x]=0;
    }
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++) cin>>h[i];
    dfs(1,1);
    h[1]=h[res[1]],h[2]=h[res[2]],h[3]=h[res[3]];
    sort(h+1,h+4);
    cout<<h[1]<<" "<<h[2]<<" "<<h[3]<<endl;
    return 0;
}

优化思路(AC):

#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
const int N=1e5+5;
int n,h[N];
vector<int>ans[N];
int main(){
    cin>>n;
    for(int i=0;i<n;i++) cin>>h[i];
    sort(h,h+n);
    //遍历一遍把数放入其因子中
    for(int i=0;i<n;i++){
        for(int j=1;j<=sqrt(h[i]);j++){
            if(h[i]%j==0){
                ans[j].push_back(h[i]);
                if(h[i]/j!=j) ans[h[i]/j].push_back(h[i]);
            }
        }
    }
    //从最大的因子开始遍历,个数不低于3就可以输出
    for(int i=N-1;i>=0;i--){
        if(ans[i].size()>=3){
            cout<<ans[i][0];
            for(int j=1;j<3;j++){
                cout<<" "<<ans[i][j];
            }
            break;
        }
    }
    return 0;
}

F.数字接龙

这题考试时候没想明白如何判断路径是否交叉,就只会dfs出所有答案可能的情况,折腾将近一个小时还没解决,最后无奈提交了样例还有-1这个情况...

实际上对于斜方向进行判断时,只需判断对于斜边的两个坐标是否被选中(AC):

#include<iostream>
#include<string>
using namespace std;
int n,k,a[15][15],endd=0;
bool flag[15][15];
int dx[8]={-1,-1,0,1,1,1,0,-1};
int dy[8]={0,1,1,1,0,-1,-1,-1};
string ans;
//寻找方向函数
int direction(int x,int y){
    if(a[x][y]==k-1) return 0;
    else return a[x][y]+1;
}
//回溯字符串函数
string delete_last(string s){
    if(s.size()==1) return "";//注意:大小为1时返回空
    string temp="";
    for(int i=0;i<=s.size()-2;i++) temp+=s[i];
    return temp;
}
//核心函数dfs
void dfs(int x,int y){
    flag[x][y]=true;
    if(x==n&&y==n&&ans.size()==n*n-1){
        cout<<ans<<endl;
        //只要找到字典序最小的,找到后标记endd
        endd++;
        return ;
    }
    int dir=direction(x,y);
    for(int i=0;i<=7;i++){
        int xx=x+dx[i],yy=y+dy[i];
        if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&a[xx][yy]==dir&&flag[xx][yy]==false){
            //判断斜方向情况,i才是真正的方向,direction只是方向的值
            if(i==1&&flag[x-1][y]&&flag[x][y+1]) continue;
            else if(i==3&&flag[x][y+1]&&flag[x+1][y]) continue;
            else if(i==5&&flag[x+1][y]&&flag[x][y-1]) continue;
            else if(i==7&&flag[x-1][y]&&flag[x][y-1]) continue;
            else{
                flag[xx][yy]=true;
                ans+=to_string(i);
                dfs(xx,yy);
                //在回溯时,特判一下已经找到答案的情况
                if(endd) return ;
                //回溯
                flag[xx][yy]=false;
                ans=delete_last(ans);
            }
        }
    }
    return ;
}
int main(){
    cin>>n>>k;
    //注意:k的值不可能大于pow(n,2)
    if(k>n*n){
        puts("-1");
        return 0;
    }
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>a[i][j];
    dfs(1,1);
    //利用endd标记是否成功dfs
    if(!endd) puts("-1");
    return 0;
}

G.爬山

这题利用STL的优先队列进行模拟,考试时候魔法一和魔法二相同时候的情况没完善明确,因此下面这段代码肯定会有问题,但考完试我隐约记得while(m--)好像被我写成了while(n--),我真是个**:

#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,p,q,h[N];
ll ans;
priority_queue<int,vector<int>,less<int>>pq;
int magic(int x){
    int a=sqrt(x);
    int b=x/2;
    if(a>b) return 2;
    else if(a<b) return 1;
    else return 0;
}
int main(){
    cin>>n>>p>>q;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        pq.push(x);
    }
    int m=p+q;
    while(m--){
        int t=pq.top();
        pq.pop();
        if(p>0&&q>0){
            int tt=magic(t);
            if(tt==0){
                if(q>p) pq.push(t/2),q--;
                else pq.push((int)sqrt(t)),p--;
            }
            else if(tt==1){
                pq.push((int)sqrt(t));
                p--;
            }
            else{
                pq.push(t/2);
                q--;
            }
        }
        else if(p>0&&q<=0){
            pq.push((int)sqrt(t)),p--;
        }
        else if(q>0&&p<=0){
            pq.push(t/2),q--;
        }
        else{
            break;
        }
    }
    while(pq.size()){
        ans+=pq.top();
        pq.pop();
    }
    cout<<ans<<endl;
    return 0;
}

HACK数据:

2 1 1
49 48

H.拔河

这题考试时候直接理解错题目了(哭),以为每一人都要参加拔河,估计直接零蛋了haha

所以做题时一定要认真把题目读清楚...

暴力枚举两个连续区间的左右端点:

#include<iostream>
using namespace std;
typedef long long ll;
const int N=1e3+5;
ll n,a[N],l1,r1,l2,r2,ans=1e18;//不开浪浪见祖宗...
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){//前缀和
        cin>>a[i];
        a[i]+=a[i-1];
    }
    for(int l1=1;l1<=n;l1++){
        for(int r1=1;r1<=n;r1++){
            for(int l2=1;l2<=n;l2++){
                for(int r2=1;r2<=n;r2++){
                    if(l1<=r1&&r1<l2&&l2<=r2){
                        ll sum1=a[r1]-a[l1-1];
                        ll sum2=a[r2]-a[l2-1];
                        ans=min(ans,abs(sum2-sum1));
                    }
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

前缀和+multiset(AC): 

#include<iostream>
#include<set>
using namespace std;
typedef long long ll;
const int N=1e3+5;
ll n,a[N],ans=1e18;
multiset<ll>s;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        a[i]+=a[i-1];
    }
    //利用multiset(有序并且可以重复)记录所有可能的区间
    for(int l=1;l<=n;l++) for(int r=1;r<=n;r++) if(r>=l) s.insert(a[r]-a[l-1]);
    //枚举左区域的右端点
    for(int r=1;r<n;r++){
        //删除以r为左端点的所有区间,因为接下来右区间是从r+1开始选择
        //如果保留之前的以r为左端点的右区间之和,会影响答案
        for(int i=r;i<=n;i++) s.erase(s.find(a[i]-a[r-1]));
        //枚举左区间的左端点
        for(int l=1;l<=r;l++){
            //计算左区间
            ll temp=a[r]-a[l-1];
            auto x=s.lower_bound(temp);
            //multiset.lower_bound(key)函数返回一个迭代器
            //返回第一个>=key的元素
            //如果key>容器max,则返回当前容器中最后一个元素的位置
            if(x!=s.end()){
                ans=min(ans,abs(*x-temp));//和temp右侧的*x更新ans
            }
            if(x!=s.begin()){
                x--;//先向左移动x
                ans=min(ans,abs(*x-temp));//和temp左侧的*x更新ans
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

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

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

相关文章

快速掌握Element-Ul,构建高效网页应用【AI写作】

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…

JavaScript继承的方法和优缺点

原型链继承 让一个构造函数的原型是另一个类型的实例&#xff0c;那么这个构造函数new出来的实例就具有该实例的属性。 优点&#xff1a; 写法方便简洁&#xff0c;容易理解。 缺点&#xff1a; 在父类型构造函数中定义的引用类型值的实例属性&#xff0c;会在子类型原型上…

逻辑回归实战 -- 是否通过考试

http://链接: https://pan.baidu.com/s/1-uy-69rkc4WjMpPj6iRDDw 提取码: e69y 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 数据集下载链接 这是个二分类问题&#xff0c;通过x1,x2两个指标得出是否通过考试的结论。 逻辑回归的激活函数是sigmoid函数&…

STM32单片机实战开发笔记-EXIT外部中断检测

嵌入式单片机开发实战例程合集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/11av8rV45dtHO0EHf8e_Q0Q?pwd28ab 提取码&#xff1a;28ab EXIT模块测试 功能描述 外部中断/事件控制器由19个产生事件/中断要求的边沿检测器组成。每个输入线可以独立地配置输入类型&a…

P9422 [蓝桥杯 2023 国 B] 合并数列

P9422 [蓝桥杯 2023 国 B] 合并数列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 用队列即可 当两个队列队首&#xff1a;a b &#xff0c;弹出 当a < b&#xff0c;把a加给其后一个元素&#xff0c;弹出a 当b < a&#xff0c;把b加给其后一个元素&#xff0c;弹出…

Eclipse 开创性地集成 Neon Stack,将 EVM 兼容性带到 SVM 网络

2024年5月2日&#xff0c;全球——在塑造区块链网络的战略联盟的过程中&#xff0c;Eclipse 通过集成 Neon EVM 核心团队开发的技术堆栈 Neon Stack&#xff0c;成为首个打破 EVM-SVM 兼容性障碍的生态。 Eclipse 旨在通过结合以太坊和 Solana 的最佳特性&#xff0c;来重构区…

2024年钉钉群直播回放如何永久保存

工具我已经打包好了&#xff0c;有需要的自己取一下 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;1234 --来自百度网盘超级会员V10的分享 1.首先解压好我给大家准备好的压缩包 2.再把逍遥一仙下载器压缩包也解压一下 3.打开逍遥一仙下载器文件夹里面的M3U8…

华为云耀云服务器开放端口

博客主页&#xff1a;花果山~程序猿-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一.华为云控制台开放端口 寻找到安全组信息 2. 添加开放的端口信息 3. 检查是否成…

常用AI工具分享 + IDEA内使用通义灵码

引言 随着人工智能技术的飞速发展&#xff0c;AI工具已经渗透到我们日常生活和工作的各个领域&#xff0c;带来了前所未有的便利。现在我将分享一下常用的AI工具&#xff0c;以及介绍如何在IDEA中使用通义灵码。 常用AI工具 1. 通义灵码 (TONGYI Lingma) - 由阿里云开发的智能…

STM32的TIM输入捕获和PWMI详解

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. IC输入捕获 2. 频率测量 3. 主模式、从模式、触发源选择 4. 输入捕获基本结构 5. PWMI模式 6. 代码示例 6.1 PWM.c 6.2 PWM.h 6.3 IC.c 6.4 IC.h 6.5 完整工程文件 输出比较可以看下面这篇…

Covalent Network(CQT)为 Arbitrum 生态提供 250 万美元的资助,以促进 Web3 的创新与发展

Covalent Network&#xff08;CQT&#xff09;作为 Web3 领先的“数据可用性”层&#xff0c;宣布将提供 250 万美元的资金以支持 Arbitrum 生态项目&#xff0c;包括 Arbitrum One、Nova、Orbit 或 Stylus。此举旨在通过提供资源和帮助&#xff0c;推动利用 Arbitrum 网络上 C…

华为机考入门python3--(20)牛客20- 密码验证合格程序

分类&#xff1a;字符串 知识点&#xff1a; 遍历字符串的每个字符 for char in my_str: 可以直接比较字符范围 a < char < z 列表统计元素个数 my_list.count(elem) 寻找子串 my_str.find(sub_str) 题目来自【牛客】 import re import sysdef check_…

信息泄露.

一&#xff0c;遍历目录 目录遍历&#xff1a;没有过滤目录相关的跳转符号&#xff08;例如&#xff1a;../&#xff09;&#xff0c;我们可以利用这个目录找到服务器中的每一个文件&#xff0c;也就是遍历。 tipe&#xff1a;依次点击文件就可以找到flag 二&#xff0c;phpi…

AI视频教程下载:零代码创建AI智能体、AI Agents和ChatGPT的Gpts

这门课程专注于提示工程的掌握&#xff0c;教你以精确的方式引导GPT&#xff0c;利用它们的生成能力产生卓越的AI驱动结果。一步一步地&#xff0c;你将学会创建多样化的GPT军团——每个都设计来满足特定的专业需求。 从提供个性化职业变更指导的职业教练AI&#xff0c;到以惊…

uniapp 监听APP切换前台、后台插件 Ba-Lifecycle

监听APP切换前台、后台 Ba-Lifecycle 简介&#xff08;下载地址&#xff09; Ba-Lifecycle 是一款uniapp监听APP切换前台、后台的插件&#xff0c;简单易用。 截图展示 也可关注博客&#xff0c;实时更新最新插件&#xff1a; uniapp 常用原生插件大全 使用方法 在 script…

可视化大屏应用场景:智慧安防,保驾护航

hello&#xff0c;我是大千UI工场&#xff0c;本篇分享智慧安防的大屏设计&#xff0c;关注我们&#xff0c;学习N多UI干货&#xff0c;有设计需求&#xff0c;我们也可以接单。 实时监控与预警 可视化大屏可以将安防系统中的监控画面、报警信息、传感器数据等实时展示在大屏上…

k8s笔记 | Ingress

安装Ingress 添加helm创库 Installation Guide - Ingress-Nginx Controller Ingress | Kubernetes 下载包 将 文件helm 放到 /usr/local/bin/ 并给到执行权限 # 添加可执行权限 chmod ux helm # 测试是否能运行 helm version# 结果 version.BuildInfo{Version:"v3.14…

快速批量重命名文件(夹)

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 我这里处理这4个文本&#xff0c;实际可以处理任意数量的文本和文件夹 1、打开工具&#xff0c;进入文件批量复制版块 2、点击“重命名” 3、把要重命名的…

从0开始学习制作一个微信小程序 学习部分(6)组件与事件绑定

系列文章目录 学习篇第一篇我们讲了编译器下载&#xff0c;项目、环境建立、文件说明与简单操作&#xff1a;第一篇链接 第二、三篇分析了几个重要的配置json文件&#xff0c;是用于对小程序进行的切换页面、改变图标、控制是否能被搜索到等的操作第二篇链接、第三篇链接 第四…

【算法】数字接龙 走迷宫问题的一般处理思路

前言 其实走迷宫就是一个普普通通的深搜回溯嘛&#xff0c;但是我之前做的很多题都是在一个二维的地图上&#xff0c;只能上下左右四个方向走迷宫&#xff0c;在做数字接龙这道题的时候&#xff0c;相当于可以往8个方向走&#xff0c;虽然逻辑上不变&#xff0c;但按照我之前的…