2017年第八届 蓝桥杯C组 C/C++决赛题解
蓝桥杯历年国赛真题汇总:Here
1.哥德巴赫分解
哥德巴赫猜想认为:不小于4的偶数都可以表示为两个素数的和。
你不需要去证明这个定理,但可以通过计算机对有限数量的偶数进行分解,验证是否可行。
实际上,一般一个偶数会有多种不同的分解方案,我们关心包含较小素数的那个方案。
对于给定数值范围,我们想知道这些包含较小素数方案中最大的素数是多少。
比如,100以内,这个数是19,它由98的分解贡献。
你需要求的是10000以内,这个数是多少?
答案:173
const int N = 10000;
vector<int>prime;
bool vis[10010];
int ans;
void check(int n) {
for (int i = 0; i < prime.size(); ++i) {
int r = n - prime[i];
if (vis[r]) {
ans = max(ans, prime[i]);
return ;
}
}
}
void solve() {
memset(vis, true, sizeof(vis));
for (int i = 2; i < N; ++i)
if (vis[i])for (int j = i + i; j < N; j += i)vis[j] = false;
for (int i = 2; i < N; ++i)if (vis[i])prime.push_back(i);
for (int i = 4; i < 10000; i += 2)check(i);
cout << ans << "\n";
}
2.数字划分
w星球的长老交给小明一个任务:
1,2,3...16 这16个数字分为两组。
要求:
这两组数字的和相同,
并且,两组数字的平方和也相同,
并且,两组数字的立方和也相同。
请你利用计算机的强大搜索能力解决这个问题。
并提交1所在的那个分组的所有数字。
这些数字要从小到大排列,两个数字间用一个空格分开。
即类似:1 4 5 8 ... 这样的答案。
注意,只提交这一组数字,不要填写任何多余的内容。
笨笨有话说:
只要一个组的成员确定了,另一个组的成员也就确定了。枚举一个组的成员就可以了。
凭直觉,两个组的成员数目不会差太多吧。
歪歪有话说:
既然求 1 所在的那个组,那只要枚举剩余的成员就可以了。
貌似都是8个成员的可能性很大啊。
答案:1 4 6 7 10 11 13 16
爆搜
bool vis[17];
void dfs(int pos, int cnt) {
if (cnt == 8) {
int sum1 = 0, sum2 = 0, sum11 = 0, sum22 = 0;
for (int i = 1; i <= 16; ++i) {
if (!vis[i])sum1 += i * i, sum2 += i * i * i;
else sum11 += i * i, sum22 += i * i * i;
}
if (sum1 == sum11 and sum2 == sum22) {
for (int i = 1; i <= 16; ++i)if (!vis[i]) cout << i << " " ;
cout << "\n"; return; // 找到一组就直接推出即可
}
return ;
}
for (int i = pos + 1; i <= 16; ++i) {
if (!vis[i])continue;
vis[i] = false;
dfs(i, cnt + 1);
vis[i] = true;
}
}
3.表达式计算
虽然我们学了许久的程序设计,但对于简单的四则混合运算式,如果让我们完全白手起家地编程来解析,还是有点棘手。
这里,我们简化一下问题,假设只有加法和乘法,并且没有括号来改变优先级。
再假设参加运算的都是正整数。
在这么多的限制条件下,表达式的解析似乎简单了许多。
下面的代码解决了这个问题。请仔细阅读源码,并填写划线部分缺少的代码。
#include <stdio.h>
int f3(const char* s, int begin, int end) {
int sum = 0;
int i;
for (i = begin; i < end; i++) {
if (s[i] == ' ') continue;
sum = sum * 10 + (s[i] - '0');
}
return sum;
}
int f2(const char* s, int begin, int end) {
int p = begin;
int pro = 1;
while (1) {
int p0 = p;
while (p != end && s[p] != '*') p++;
pro *= _______________________________; //填空
if (p == end) break;
p++;
}
printf("f2: pro=%d\n", pro);
return pro;
}
int f(const char* s) {
int p = 0;
int sum = 0;
while (1) {
int p0 = p;
while (s[p] != 0 && s[p] != '+') p++;
sum += f2(s, p0, p);
if (s[p] == 0) break;
p++;
}
return sum;
}
int main() {
int x = f("12+18+5*4*3+10");
printf("%d\n", x); // 100
return 0;
}
注意:只填写划线处缺少的内容,不要填写已有的代码或符号,也不要填写任何解释说明文字等。
答案:
f3(s, p0, p)
仔细阅读代码即可
4.小数第n位
我们知道,整数做除法时,有时得到有限小数,有时得到无限循环小数。
如果我们把有限小数的末尾加上无限多个0,它们就有了统一的形式。
本题的任务是:在上面的约定下,求整数除法小数点后的第n位开始的3位数。
输入:
一行三个整数:a b n,用空格分开。a是被除数,b是除数,n是所求的小数后位置(0<a,b,n<1000000000)
输出:
一行3位数字,表示:a除以b,小数后第n位开始的3位数字。
比如:
输入:
1 8 1
程序应该输出:
125
再比如:
输入:
1 8 3
程序应该输出:
500
再比如:
输入:
282866 999000 6
程序应该输出:
914
提交时,注意选择所期望的编译器类型。
笨笨有话说:
这个除法小学就会算啊,模拟手算除法的过程就可以了吧。
只是数有点大啊....
管它呢,能算多远算多远....
歪歪有话说:
如果我能确定循环节从哪里开始到哪里结束,再大的数不过就是与它取模的余数等价啊
【思路】
模拟除法。
13 / 7 = 1.85714285...
这里求小数部分,所有取模忽略掉整数部分
13 / 7 -> 6 / 7
第一位:(小数点后第几位,以下同)6 * 10 / 7 = 8;
得到第一位后的余数:6 * 10 % 7 = 4
那么第二位:4 * 10 / 7 = 5
得到第二位后的余数:4 * 10 % 7 = 5
第三位:5 * 10 / 7 = 7
依此类推
void solve() {
ll a, b, n;
cin >> a >> b >> n;
a %= b;
while (n > 10) {
a *= 1E10; a %= b; n -= 10;
}
for (int i = 0; i < n + 2; ++i) {
a *= 10;
if (i >= n - 1)cout << a / b;
a %= b;
}
}
5.分考场
n个人参加某项特殊考试。
为了公平,要求任何两个认识的人不能分在同一个考场。
求最少需要分几个考场才能满足条件。
输入格式:
第一行,一个整数n(1<n<100),表示参加考试的人数。
第二行,一个整数m,表示接下来有m行数据
以下m行每行的格式为:两个整数a,b,用空格分开 (1<=a,b<=n) 表示第a个人与第b个人认识(编号从1开始)。
输出格式:
一行一个整数,表示最少分几个考场。
例如:
输入:
5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
程序应该输出:
4
再比如:
输入:
5
10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
则程序应该输出:
5
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
【思路】
一开始以为是并查集之类的连通图大小的问题,写了一发结果只通过 30% 的数据,重新审题发现其实就是图的着色问题:给定顶点数和边,求至少需要多少种颜色对图进行涂色能是相邻顶点颜色不同。
const int N = 110, inf = 0x3f3f3f3f;
int e[N][N];
int vis[N][N]; // vis[i][j] = t表示第i个考场里面第j个人是t
int cnt[N]; // 记录每个考场种的学生数量(对应的vis)
int ans = inf, n, m;
void dfs(int id, int num) {// id表示第id个学生,num表示当前考场编号
if (num >= ans)return;
if (id > n) { // 学生已经安排完了
ans = min(ans, num);// 更新当前最优解(不要用min可能超时)
return;
}
for (int i = 1; i <= num; ++i) {// 先看之前分配为的考场里面能不能进去
int rnd = 0;// 表示id学生与第i个考场里面的人不认识的数量
for (int j = 1; j <= cnt[i]; ++j) // cnt[i]表示第i个考场里面的人数
if (e[id][vis[i][j]] == 0)rnd ++;
if (rnd == cnt[i]) { // 如果都不认识
vis[i][++cnt[i]] = id;
dfs(id + 1, num);
cnt[i]--;// 回溯
}
}
// 现有考场都不行,就要增加考场
vis[num + 1][++cnt[num + 1]] = id;
dfs(id + 1, num + 1);
--cnt[num + 1]; // 回溯
}
void solve() {
cin >> n >> m;
while (m--) {
int u, v;
cin >> u >> v;
e[u][v] = e[v][u] = 1;
}
dfs(1, 0);
cout << ans << "\n";
}
6.合根植物
w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。
这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。
如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?
输入格式:
第一行,两个整数m,n,用空格分开,表示格子的行数、列数(1<m,n<1000)。
接下来一行,一个整数k,表示下面还有k行数据(0<k<100000)
接下来k行,第行两个整数a,b,表示编号为a的小格子和编号为b的小格子合根了。
格子的编号一行一行,从上到下,从左到右编号。
比如:5 * 4 的小格子,编号:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
样例输入:
5 4
16
2 3
1 5
5 9
4 8
7 8
9 10
10 11
11 12
10 14
12 16
14 18
17 18
15 19
19 20
9 13
13 17
样例输出:
5
其合根情况参考图[p1.png]
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 2000ms
待补
2017年第八届 蓝桥杯C组 C/C++决赛题解的更多相关文章
- 2018年蓝桥杯A组C/C++决赛题解
2018年第九届蓝桥杯A组C/C++决赛题解 点击查看视频题解 点击查看2018年蓝桥杯A组C/C++决赛题目(不含答案) 1:三角形面积 画个图,求三角形面积,可以用外接长方形 - 其他多余区域面积 ...
- 2016年蓝桥杯B组C/C++决赛题解
2016年第七届蓝桥杯B组C/C++决赛题解 2016年蓝桥杯B组C/C++决赛题目(不含答案) 1.一步之遥 枚举解方程,或者套模板解线性方程 #include<bits/stdc++.h&g ...
- 2015年蓝桥杯B组C/C++决赛题解
2015年第六届蓝桥杯B组C/C++决赛题解 点击查看2015年第六届蓝桥杯B组C/C++国赛题目(不含答案) 1.积分之迷 三重循环 枚举A,B,C的值,如果满足两个条件:3个A + 7个B ...
- 2018年蓝桥杯B组C/C++决赛题解
2018年第九届蓝桥杯B组C/C++决赛题解 点击查看2018年蓝桥杯B组C/C++决赛题目(不含答案) 1.换零钞 ok 枚举 设x表示1元钱的个数,y表示2元钱的个数,z表示5元钱的个数 x+21 ...
- 2017年蓝桥杯B组C/C++决赛题解
2017年蓝桥杯B组C/C++决赛题目(不含答案) 1.36进制 ok 求36进制,类比二进制转10进制,36^3 + 36^2 + 36^1 + 36^0 2.磁砖样式 ok dfs搜索 我自己写的 ...
- 2017年蓝桥杯B组C/C++决赛题目
2017年第八届蓝桥杯B组C/C++决赛题目 点击查看2017年蓝桥杯B组C/C++决赛题解 1.36进制 对于16进制,我们使用字母A-F来表示10及以上的数字. 如法炮制,一直用到字母Z, ...
- 2018年蓝桥杯A组C/C++决赛题目
2018年蓝桥杯A组C/C++决赛题目 2018年蓝桥杯A组C/C++决赛题解 1:三角形面积 已知三角形三个顶点在直角坐标系下的坐标分别为: (2.3, 2.5) (6.4, 3.1) (5 ...
- 2016年蓝桥杯B组C/C++决赛题目
2016年第七届蓝桥杯B组C/C++决赛题目 点击查看2016年第七届蓝桥杯B组C/C++决赛题解 1.一步之遥 从昏迷中醒来,小明发现自己被关在X星球的废矿车里. 矿车停在平直的废弃的轨道上. 他的 ...
- 2018年蓝桥杯B组C/C++决赛题目
自己的博客排版,自我感觉略好一点. 先放上题目. 点击查看2018年蓝桥杯B组C/C++决赛题目题解 1.换零钞 x星球的钞票的面额只有:100元,5元,2元,1元,共4种. 小明去x星旅游, ...
- 2015年蓝桥杯B组C/C++决赛题目
2015年第六届蓝桥杯B组C/C++国赛题目 点击查看2015年第六届蓝桥杯B组C/C++国赛题解 1.积分之迷 小明开了个网上商店,卖风铃.共有3个品牌:A,B,C. 为了促销,每件商品都会 ...
随机推荐
- CTA策略介绍
CTA策略更多的时候是一种投资方法,更准确的说,主要投资于衍生品的.比较系统化规则化的投资方法都可以称作CTA投资,它并不拘泥于量化或是主动,其具有相当的生命力,会长期存在. CTA策略的收入来源是多 ...
- 在路上---学习篇(一)Python 数据结构和算法 (5)二分查找、二叉树遍历
独白: 利用算法进行查找指定元素,最近学习二分查找和二叉树遍历.二分查找前提是在有序中进行查找,二叉树引入了树的概念.树的概念其中有许多小知识点,也是一种新的数据结构.还是之前的感悟,需了解其本质才会 ...
- vivado仿真(无需testbench)
vivado仿真(无testbench) 实现步骤 新建一个工程并添加自己编写的Verilog文件 添加后vivado会自动识别文件中的module 创建block design文件,添加模块 添加前 ...
- 【VMware vCenter】管理平台出现备份作业状态告警,VAMI后台备份任务未能运行,点击手动备份提示FTP位置不可用等问题的处理过程。
VMware vCenter提供了一个备份/还原功能,以便在当vCenter本身出现故障且无法恢复的情况下,使用该功能可以将出故障的vCenter配置文件还原到一个新的vCenter上,这样就无需再重 ...
- Linux机器在命令行操作时开启/关闭代理
命令行操作时,如果需要连接通过代理才能访问的地址,可以通过配置当前shell的配置文件来手动开启/关闭代理 注意:代理只对当前用户当前shell生效,切换用户或者重新连接需要重新开启代理 修改当前用户 ...
- json数组根据某属性去重
数据: let arry = [ {name: "张三", age: 23, work: '计算机'}, {name: "王五", age: 29, work: ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-35-处理web页面定位toast-上篇
1.简介 在使用appium写app自动化的时候介绍toast的相关元素的定位,在Web UI测试过程中,也经常遇到一些toast(出现之后一闪而过,不留下一点点痕迹),那么这个toast我们这边如何 ...
- pta三次实验的总结
第一次pta作业 在pta第一次作业,因为是第一次作业所以大体是比较容易,但是也有几个要注意的点,就是两个double的值相加减相乘的值与实际值会有一定的误差,误差大小为0.0000001,所以在写p ...
- PHP异步通信
目录 PHP swoole websocket服务器端 websocket 客户端 直播平台 基于宝塔nginx安装Nginx-rtmp-module搭建流媒体服务器 web H5端拉流 其他 PHP ...
- JPA动态注册多数据源
背景 目前已经是微服务的天下,但是随着业务需求的日益增长,部分应用还是出现了需要同时连接多个数据源操作数据的技术诉求. 需要对现有的技术架构进行优化升级,查阅了下网上的文章,基本都是照搬的同一篇文章, ...