2021第十二届蓝桥杯B组省赛C/C++做题过程与反思
2021第十二届蓝桥杯B组省赛C/C++做题过程与反思
鄙人大一,第一次有幸参加蓝桥杯b组c。以下是本人的做题全过程,注意了!!!!不一定是正确答案!! 如果有误,还请大佬们指点指点。
试题 A: 空间
【问题描述】
小蓝准备用 256MB 的内存空间开一个数组,数组的每个元素都是 32 位
二进制整数,如果不考虑程序占用的空间和维护内存需要的辅助空间,请问
256MB 的空间可以存储多少个 32 位二进制整数?
思路
当时想错了,想都没想直接就除了32…答案应该是 67108864(256 * 1024 * 1024 / 4) 。
试题 B: 卡片
【问题描述】
小蓝有很多数字卡片,每张卡片上都是数字 0 到 9。
小蓝准备用这些卡片来拼一些数,他想从 1 开始拼出正整数,每拼一个,
就保存起来,卡片就不能用来拼其它数了。
小蓝想知道自己能从 1 拼到多少。
例如,当小蓝有 30 张卡片,其中 0 到 9 各 3 张,则小蓝可以拼出 1 到 10,
但是拼 11 时卡片 1 已经只有一张了,不够拼出 11。
现在小蓝手里有 0 到 9 的卡片各 2021 张,共 20210 张,请问小蓝可以从 1
拼到多少?
思路
做的时候,信誓旦旦打出代码,提交答案 3182 赛后看到别人 3181 ???王德发??好吧是我没减1…草率了。
#include <bits/stdc++.h>
using namespace std;
int a[10];
bool judge(int i)
{while(i){if(a[i%10]>=1){a[i%10]--;}else return 0;i/=10;}return 1;
}
int main()
{for(int i=0;i<=9;i++){a[i]=2021;}for(int i=1;i<=100000;i++){if(judge(i)){;}else {cout<<i-1;break;}}return 0;
}
试题 C: 直线
【问题描述】
在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上,
那么这些点中任意两点确定的直线是同一条。
给定平面上 2 × 3 个整点 {(x, y)|0 ≤ x < 2, 0 ≤ y < 3, x ∈ Z, y ∈ Z},即横坐标
是 0 到 1 (包含 0 和 1) 之间的整数、纵坐标是 0 到 2 (包含 0 和 2) 之间的整数
的点。这些点一共确定了 11 条不同的直线。
给定平面上 20 × 21 个整点 {(x, y)|0 ≤ x < 20, 0 ≤ y < 21, x ∈ Z, y ∈ Z},即横
坐标是 0 到 19 (包含 0 和 19) 之间的整数、纵坐标是 0 到 20 (包含 0 和 20) 之
间的整数的点。请问这些点一共确定了多少条不同的直线。
思路
这题做的时候呢,一开始是想手写看看能不能写出来,推了有那么一段时间,用排列组合,然后排除同x同y的,最后发现…不对劲啊,斜着也可以重合。。。然后突然想到19年还是20年有一题是线分成多少个面的…要暴力存之前的线,然后发现套在这个题上也可以,所以就有了以下的思路。
直接开个结构体数组存每条线的k,b值最后看结构体数组的大小就是答案了,。但是写的时候有个问题,垂直于x,y的时候怎么处理?然后我就想,直接不处理了,画图发现垂直于x的不就是20条,垂直于y的不就是21条。那好办了,于是就有了下面的代码。答案应该是 40257
#include <bits/stdc++.h>
using namespace std;
struct node {double k,b;
}s[1000000];
int p; //线的个数
double k,b;
void f(int x1,int y1,int x2,int y2)
{k=(double)(y1-y2)/(double)(x1-x2);//不用考虑x1==x2,y1==y2了 b=(double)(y1*(x1-x2)-x1*(y1-y2))/(x1-x2); //手推公式
}
int main()
{int n=19,m=20;for(int x1=0;x1<=n;x1++){for(int y1=0;y1<=m;y1++){for(int x2=0;x2<=n;x2++){for(int y2=0;y2<=m;y2++){if(x1==x2||y1==y2){ //特殊处理,在答案直接加垂直于x,y的线,所以不用算 continue;}f(x1,y1,x2,y2); //计算当前两点的k,b值int flag=1;for(int i=1;i<=p;i++){if(k==s[i].k&&b==s[i].b){flag=0;break;}} if(flag){ //如果之前没有这个线,就可以存起来 s[++p].k=k;s[p].b=b;}}}}}cout<<p+20+21;//加上垂直的答案; return 0;
}
试题 D: 货物摆放
【问题描述】
小蓝有一个超大的仓库,可以摆放很多货物。
现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝
规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、
宽、高。
小蓝希望所有的货物最终摆成一个大的立方体。即在长、宽、高的方向上
分别堆 L、W、H 的货物,满足 n = L × W × H。
给定 n,请问有多少种堆放货物的方案满足要求。
例如,当 n = 4 时,有以下 6 种方案:1×1×4、1×2×2、1×4×1、2×1×2、
2 × 2 × 1、4 × 1 × 1。
请问,当 n = 2021041820210418 (注意有 16 位数字)时,总共有多少种
方案?
思路
一开始想着能不能暴力以下??估计大家都有这样的想法吧,当然了,肯定跑不出来的,这么大的数。然后我就往下看了,最后才回来做的,我发现好像有个规律,找三个数相乘等于一个数,其实这三个数都是这个数的因子。所以思路就出来了,找出n的所有因子,三层循环暴力一下组合方法就行了。答案应该是 2430
#include <bits/stdc++.h>
#define ll long long
using namespace std;
set <ll > s; //用set能避免去重的麻烦操作
ll a[100000],p; //把set的数存到数组,又能化简遍历难度。
int main()
{ll n=2021041820210418;for(ll i=1;i<=sqrt(n);i++){ //开方优化if(n%i==0){s.insert(i); //无脑放就行,反正能去重 s.insert(n/i);}}set <ll > :: iterator it;for(it=s.begin();it!=s.end();it++){a[++p]=*it;}int co=0;for(int i=1;i<=p;i++){for(int j=1;j<=p;j++){for(int k=1;k<=p;k++){if(a[i]*a[j]*a[k]==n){co++;}}}}cout<<co;return 0;
}
试题 E: 路径
【问题描述】
小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图
中的最短路径。
小蓝的图由 2021 个结点组成,依次编号 1 至 2021。
对于两个不同的结点 a, b,如果 a 和 b 的差的绝对值大于 21,则两个结点
之间没有边相连;如果 a 和 b 的差的绝对值小于等于 21,则两个点之间有一条
长度为 a 和 b 的最小公倍数的无向边相连。
例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无
向边,长度为 24;结点 15 和结点 25 之间有一条无向边,长度为 75。
请计算,结点 1 和结点 2021 之间的最短路径长度是多少。
思路
这个应该蛮容易想到的,就是图论嘛,根据题意存边,存完之后跑一次弗洛伊德就行了,虽然复杂度高,但是代码简洁,用dij什么也行。代码稍微复杂一点。答案应该是 10266837
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int G[2050][2050];
int INF=200000000;
int gcd(int a,int b)
{if(b==0)return a;return gcd(b,a%b);
}
int main()
{for(int i=1;i<=2021;i++){for(int j=1;j<=2021;j++){G[i][j]=INF;}}for(int i=1;i<=2021;i++){ //按题意建图 for(int j=1;j<=2021;j++){if(abs(i-j)<=21){int lcm=i*j/gcd(i,j); //最小公倍数 G[i][j]=min(G[i][j],lcm); //注意不要直接存,会有重边 }}}for(int k=1;k<=2021;k++){ //弗洛伊德模板 for(int i=1;i<=2021;i++){if(G[i][k]==INF)continue; //小小优化 for(int j=1;j<=2021;j++){if(G[k][j]==INF)continue;G[i][j]=min(G[i][j],G[i][k]+G[k][j]);}}}cout<<G[1][2021];return 0;
}
试题 F: 时间显示
【问题描述】
小蓝要和朋友合作开发一个时间显示的网站。在服务器上,朋友已经获取
了当前的时间,用一个整数表示,值为从 1970 年 1 月 1 日 00:00:00 到当前时
刻经过的毫秒数。
现在,小蓝要在客户端显示出这个时间。小蓝不用显示出年月日,只需要
显示出时分秒即可,毫秒也不用显示,直接舍去即可。
给定一个用整数表示的时间,请将这个时间对应的时分秒输出。
【输入格式】
输入一行包含一个整数,表示时间。
【输出格式】
输出时分秒表示的当前时间,格式形如 HH:MM:SS,其中
HH 表示时,值
为 0 到 23,MM 表示分,值为 0 到 59,SS 表示秒,值为 0 到 59。时、分、秒
不足两位时补前导 0。
【样例输入 1】
46800999
【样例输出 1】
13:00:00
【样例输入 2】
1618708103123
【样例输出 2】
01:08:23
思路
这个题总体看上去不难,但是一开始我不知道毫秒跟秒怎么换算,最后是看第一个样例得出来的结果!!! 1秒等于1000毫秒,这道题比较好人,可以直接去掉毫秒,也就是一开始的n让它除以1000就行,然后得出来的结果是多少秒,然后在用多少秒除以60得出多少分钟,然后多少分钟除以60得出多少时,然后时,分,秒,都各自取模就好。注意一下输出,就行。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{ll n;cin>>n;n/=1000;ll s,f,m;//s是时,f是分,m是秒m=n;f=m/60;s=f/60;m%=60;f%=60;s%=24;if(s<=9){cout<<0<<s;}else cout<<s;cout<<':';if(f<=9){cout<<0<<f;}else cout<<f;cout<<':';if(m<=9){cout<<0<<m;}else cout<<m;return 0;
}
试题 G: 砝码称重
【问题描述】
你有一架天平和 N 个砝码,这 N 个砝码重量依次是 W1, W2, · · · , W**N。
请你计算一共可以称出多少种不同的重量?
注意砝码可以放在天平两边。
【输入格式】
输入的第一行包含一个整数 N。
第二行包含 N 个整数:W1, W2, W3, · · · , W**N。
【输出格式】
输出一个整数代表答案。
【样例输入】
3
1 4 6
【样例输出】
10
思路
一眼看上去,呦,这不是dp嘛,第二眼看上去,确认过眼神…01背包?嗯,不太像 有点特别,多了个相减,不过道理是不变的 ,但是dp的条件不知道有没有写齐全,感觉有点问题。。。 用dfs应该能过一些点,但是应该会超时。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int dp[105][100005]; //数据保证N个砝码总重不超过 100000
int n;
int v[105];
int m; //所有的重量加起来,方便dp的第二层循环
int main()
{cin>>n;for(int i=1;i<=n;i++){scanf("%d",&v[i]);m+=v[i];}for(int i=0;i<=n;i++){ //预处理0处的值 dp[i][0]=1;}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(dp[i-1][j]==1){ //不要v[i]的情况 dp[i][j]=1;}else if(j>=v[i]&&dp[i-1][j-v[i]]==1){ //加一个v[i]的情况 dp[i][j]=1;}else if(j+v[i]<=m&&dp[i-1][j+v[i]]==1){ //减一个v[i]的情况 dp[i][j]=1;}else if(v[i]>=j&&dp[i-1][v[i]-j]==1){ //把v[i]放对面的情况 dp[i][j]=1;}}}int co=0;for(int i=1;i<=m;i++){if(dp[n][i]==1){co++;}}cout<<co;return 0;
}
试题 H: 杨辉三角形
【问题描述】
下面的图形是著名的杨辉三角形:
如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下
数列:
1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, …
给定一个正整数 N,请你输出数列中第一次出现
N 是在第几个数?
【输入格式】
输入一个整数 N。
【输出格式】
输出一个整数代表答案。
【样例输入】
6
【样例输出】
13
思路
没啥思路,4000以下纯暴力,( 多了会超时 可能或许5000也行,但是我没冒险 )4000以上当做n在第n+1排的第二个处理,反正质数肯定是满足的,其他数应该也有不少满足的 用等差数列前n项和公式就行,公差为1,Sn = n+(n*(n-1))/2
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int G[5005][5005];
ll n;
int main()
{cin>>n;if(n>4000){ //或许能骗分 cout<<(n*(n+1))/2+2;return 0;}G[1][1]=1;for(int i=2;i<=n+1;i++){G[i][1]=1;for(int j=2;j<=i;j++){G[i][j]=G[i-1][j]+G[i-1][j-1];}}int now=0; //自增个数 for(int i=1;i<=n+1;i++){for(int j=1;j<=i;j++){now++;if(n==G[i][j]){ //遇到第一个就是答案 cout<<now;return 0;}}//cout<<endl;}return 0;
}
试题 I: 双向排序
【问题描述】
给定序列 (a1, a2, · · · , a**n) = (1, 2, · · · , n),即 a**i
= i。
小蓝将对这个序列进行 m 次操作,每次可能是将 a1, a2, · · · , aqi 降序排列,
或者将 aqi , aqi+1, · · · , a**n 升序排列。
请求出操作完成后的序列。
【输入格式】
输入的第一行包含两个整数 n, m,分别表示序列的长度和操作次数。
接下来 m 行描述对序列的操作,其中第 i 行包含两个整数 p**i, q**i 表示操作
类型和参数。当 p**i = 0 时,表示将 a1, a2, · · · , aqi 降序排列;当 p**i = 1 时,表示
将 aqi , aqi+1, · · · , a**n 升序排列。
【输出格式】
输出一行,包含 n
个整数,相邻的整数之间使用一个空格分隔,表示操作
完成后的序列。
【样例输入】
3 3
0 3
1 2
0 2
【样例输出】
3 1 2
思路
没有思路…只能用sort纯模拟 能过60%的点…
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[100005];
int n,m;
bool cmp(int a,int b)
{return a>b;
}
int main()
{cin>>n>>m;for(int i=1;i<=n;i++){a[i]=i;}for(int i=1;i<=m;i++){int p,q;scanf("%d%d",&p,&q);if(p==0){sort(a+1,a+1+q,cmp);}else {sort(a+q,a+1+n);}}for(int i=1;i<=n;i++){if(i!=1){ //不知道会不会卡空格 cout<<" ";}cout<<a[i];}return 0;
}
试题 J: 括号序列
【问题描述】
给定一个括号序列,要求尽可能少地添加若干括号使得括号序列变得合法,
当添加完成后,会产生不同的添加结果,请问有多少种本质不同的添加结果。
两个结果是本质不同的是指存在某个位置一个结果是左括号,而另一个是右括
号。
例如,对于括号序列 (((),只需要添加两个括号就能让其合法,有以下几
种不同的添加结果:()()()、()(())、(())()、(()()) 和 ((()))。
【输入格式】
输入一行包含一个字符串 s,表示给定的括号序列,序列中只有左括号和
右括号。
【输出格式】
输出一个整数表示答案,答案可能很大,请输出答案除以
1000000007 (即
109 + 7) 的余数。
【样例输入】
((()
【样例输出】
5
思路
没思路,也没时间想。 草率了,空了,样例都没输出一下,复制出来纯粹是为了 给有兴趣的人看一下
总结
其他感觉还行,算是正常发挥了吧,能做的都做了,不会的也依旧不会,最气人的是第一第二题都错了!!!!今年的体验感还行,明年继续。
2021第十二届蓝桥杯B组省赛C/C++做题过程与反思相关推荐
- 2021第十二届蓝桥杯Python组国赛/决赛 题解
2021第十二届蓝桥杯Python组国赛/决赛 题解 前言 2021年第十二届蓝桥杯国赛/决赛,因为疫情原因没有像往年一样前往北京参赛,而是在自己学校的机房进行考试,形式上类似蓝桥杯省赛,但由于参加国 ...
- 第十二届蓝桥杯青少年组国赛C++中级组 第1题 -- 第3题(python3实现)
12届蓝桥杯青少年组国赛C++中级组编程题 12届蓝桥杯青少年组国赛C++中级组编程题_lybc2019的博客-CSDN博客 蓝桥杯算法学习路线 | 全程制作过程公开 蓝桥杯算法学习路线 | 全程制作 ...
- 蓝桥杯|2021第十二届蓝桥杯第二次模拟赛真题与解答[Java]
记录2021年第十二届蓝桥杯第二次模拟赛真题与解题,部分答案来自网络.个人记录,菜得很. 目录 填空题 一 二 三 四 五 编程题 六 七 八 九 十 填空题 一 问题描述 请问在 1 到 2020 ...
- 2021年第十二届蓝桥杯A组省赛
时隔9个月,终于想起补题了 编程题 A. 卡片(5分) 答案:3181 分析: 简单题,直接从1开始处理每一个数,直到出现某一种卡片不够为止. #include<bits/stdc++.h> ...
- 第十二届蓝桥杯A组省赛填空题Java思路及代码合集(相乘直线货物摆放路径回路计数)
文章目录 试题 A: 相乘 试题 B: 直线 试题 C: 货物摆放 试题 D: 路径 试题 E: 回路计数 试题 A: 相乘 本题总分:5 分 [问题描述] 小蓝发现,他将 1 至 100000000 ...
- 第十二届蓝桥杯JavaB组省赛H题 杨辉三角形
早上的比赛,忘记测试用例了. 计算输入数字N在杨辉三角形中出现的第一个位置 (把杨辉三角形平铺成一个数列) 我是构建了杨辉三角,用count记录添加次数,发现N时输出count (注意特判当N是1时输 ...
- 第十二届蓝桥杯A组省赛试题 I: 双向排序(Java)
试题 I: 双向排序 本题总分:25 分 [问题描述] 给定序列 (a1, a2, · · · , an) = (1, 2, · · · , n),即 ai = i. 小蓝将对这个序列进行 m 次操作 ...
- 第十二届蓝桥杯JavaB组省赛H_杨辉三角形
一.题目: 二.题目分析: 首先这个题是我们比较熟悉的杨辉三角,需要注意的就是评测用例的范围. 三.解法 . 题目给出20%的用例是1-10 所以可以直接 枚举出1-10的即可获得2分 . 下面我第一 ...
- 第十二届蓝桥杯CB组国赛二等奖总结
虽然只是一个中游国二(全校第7),但是对我个人来说,这次获奖意义蛮大的. 首先,我在国赛前没有准备- 其实省赛前有认真准备,主要在Acwing训练. 但是省赛对我打击挺大的,当时由于认真准备了很久,对 ...
最新文章
- 云米冰箱能控制扫地机器人_用冰箱就能掌控全屋家电?云米21Face 428L确实可以...
- linux cp复制文件夹下的软连接,Linux培训:cp命令复制文件和目录
- SQL Server 数据库维护脚本合集[005]-删除数据库所有用户表
- 任务管理器启动资源管理器
- 职场与生活 八条原则 让你不再浪费时间和提高效率
- 标签传播(阅读笔记)
- javascript:鼠标拖动图标技术
- BAT批处理整人代码
- mui中双webView的刷新
- 让Firefox支持Wap浏览器功能的插件
- 飞鱼服务器 微信,飞鱼微信客服系统软件
- Android 敏感词过滤实现
- php ui设计_什么是ui设计
- antd中的disabledDate不可选择时间的处理-包含或不包含当前选择-moment
- GSoC 2015 总结
- 为什么默认排除 junit-vintage-engine ?
- 图片编辑工具哪个好?好用的图片编辑工具介绍
- C++读取局域网内其他计算机共享文件夹的文件
- 男人与女人的暧昧法则
- 如何获取抖音和快手直播间的直播流地址
热门文章
- 人生之路 — 如何处理矛盾
- Vulnhub项目:Aragog
- jersey初学者资源
- 四川对口计算机高考专业试卷,2019年对口高考试卷(计算机)文件.doc
- C++读写图片数据转成Base64格式
- 数学建模学习(64):2022美赛C题股票投资策略回顾讲解,教你正确打数学建模比赛
- css透明效果代码结构,用CSS实现背景半透明效果的方法实现_css
- unity3d 挂载脚本_Unity3D 自动添加脚本到物体上(指定脚本挂在指定位置上)
- 计算机底层:ASCII码、区位码、国标码、汉字机内码,还有字形码和输入输出编码之间的关系以及介绍
- 获取远程库与本地同步合并_如何通过合并数据库获取实时分析