2017年蓝桥杯B组C/C++决赛题目(不含答案)

1.36进制 ok

求36进制,类比二进制转10进制,36^3 + 36^2 + 36^1 + 36^0

2.磁砖样式 ok

dfs搜索

我自己写的答案不对dfs多搜了一些,原因是 判断条件不能连等于 例如abc==d 是错误的,已经改正

#include <stdio.h>
#include <string.h>
#include <map>
#include <algorithm>
using namespace std;
const int w = 3, h = 10;
int g[w][h];
int ans = 0; map<int, int> Hash; //检查2x2格子颜色是否相同
bool check_color() {
for(int i = 0; i < w; i++)
for(int j = 0; j < h; j++) {
if(i+1 < w && j+1 < h) {
if((g[i][j]+g[i][j+1]+g[i+1][j]+g[i+1][j+1]) % 4 == 0)
return false;
}
}
return true;
} void dfs(int x, int y) {
if(g[x][y] == -1) {
//横向摆放
if(y+1 < h && g[x][y+1] == -1) { for(int i = 0; i < 2; i++) {
g[x][y] = g[x][y+1] = i;
if(y == h-1) { //铺下一行
dfs(x+1, 0);
} else { //铺当前行的下一个格子
dfs(x, y+1);
}
g[x][y] = g[x][y+1] = -1;
} }
//纵向摆放
if(x+1 < w && g[x+1][y] == -1) {
for(int i = 0; i < 2; i++) {
g[x][y] = g[x+1][y] = i;
if(y == h-1) { //铺下一行
dfs(x+1, 0);
} else { //铺当前行的下一个格子
dfs(x, y+1);
}
g[x][y] = g[x+1][y] = -1;
}
}
} else {
if(x == w-1 && y == h-1) { //成功铺满
if(check_color()) {
//判断是否出现重复情况
int ret = 0, bit = 1;
for(int i = 0; i < w; i++)
for(int j = 0; j < h; j++) {
ret += g[i][j] * bit;
bit *= 2;
}
if(!Hash.count(ret)) {
Hash[ret] = 1;
ans++;
}
}
return;
}
if(y == h-1) { //铺下一行
dfs(x+1, 0);
} else { //铺当前行的下一个格子
dfs(x, y+1);
}
}
} int main() {
memset(g, -1, sizeof(g));
dfs(0, 0);
printf("%d\n", ans);
return 0;
}

3.希尔伯特曲线 0%

乱猜

4.发现环 ok

并查集判断环,dfs搜索环的路径

写dfs搜索路径是重点吧,我写的都超时了。。网上搜的一份转载我改了改

首先需要知道怎么判断环? 如不了解可以搜索:并查集判断环

其次是dfs搜索环的路径,前面并查集判断环时找到 两个点(构成了环),dfs搜索时如果从其中一个点到达了另一个点,说明成环了,中间过程经过的点就是环的路径

#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 100000+5;
int par[maxn], vis[maxn], path[maxn];
vector<int> edge[maxn];
int n, s, f; //并查集
int find(int x) {
return par[x] == x ? x : par[x] = find(par[x]);
} //dfs搜索:index表示路径上第几个点 u表示当前点的编号
void dfs(int u, int index) {
path[index] = u;//记录路径
if(u == f) {
sort(path, path + index + 1);//按题目要求先排序从小到大输出
for(int i = 0; i <= index; i++) {
printf("%d%c", path[i], i==index?'\n':' ');
}
return;
}
vis[u] = 1; //标记点已经用过
for(int i = 0; i < edge[u].size(); i++) {
int v = edge[u][i];
if(!vis[v]) dfs(v, index+1);
}
vis[u] = 0; //回溯
} int main() {
while(scanf("%d", &n) == 1) {
int u, v;
for(int i = 1; i <= n; i++) par[i] = i;
for(int i = 0; i < n; i++) {
scanf("%d%d", &u, &v);
int ru = find(u), rv = find(v);
if(ru == rv) s = u, f = v; //并查集找到两个端点 (构成环)
else {
par[ru] = rv;
edge[u].push_back(v);
edge[v].push_back(u);
}
}
memset(vis, 0, sizeof(vis));
dfs(s, 0);
}
return 0;
}

5.对局匹配 ok

30%:暴力,dfs暴力搜也行

50%:贪心

100%:先分组,再dp求出每一组的最大值,dp[i]表示前i个组的最大值;

什么是一组?

怎么求最大值?用到题意:相邻的两份不能都取 比如 x x+k x+2k 你只能按x+k 或者 x x+2k的数量取

贪心做法50%:

#include<bits/stdc++.h>
using namespace std; /*
贪心:竟然能过50%数据
统计每个数出现的次数
从1~n小到大,计算可以匹配的 i 和 i+k 中取最小值,(贪心:当前这个人不用就浪费了!所以用完他,但是这种思路是错的:有可能后面的人和后面的人+k匹配时答案更优)
特判k=0的时候
*/ const int maxn = 100005;
int cnt[2*maxn];
int a[maxn];
int n,k;
int ans = 0; int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),cnt[a[i]]++; if(k==0){
for(int i=1;i<=n;i++) ans += cnt[i]/2;
}else{
for(int i=1;i<=n;i++){
int minx = min(cnt[i],cnt[i+k]);
cnt[i] -= minx;
cnt[i+k] -= minx;
ans += minx;
}
} printf("%d",n - ans);
return 0;
}

dp做法AC:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAX_SCORE 100000
using namespace std;
const int maxn = 100000 + 5;
int cnt[MAX_SCORE+5], val[maxn], dp[maxn];
int n, k; /*
设共有x种分数,将其分为k组,每个分数满足相邻的分数值相差为k。
正如样例2中所示,共有4种分数,
将其分为1组:{1,2,3,4},这个组中任何相邻的两个分数都不能同时取,
因为它们相差k,该分组还对应了一个人数分组:{4,1,1,4},要想使得人数尽量多,
而且分数不能相差1,那么选择分数分别为{1,4},人数是4+4=8. 上述是只有一个分组的情况,
当有多个分组的时候也是同样的处理方法--尽量选择不相邻且人数最多。
对于一个人数分别为{a1,a2,...,an}的分组,可以利用动态规划算法来选择最多人数,且都不相邻。
每个ai只有选择与不选择两种可能,
假设dp(i)表示前i个人数能获得的最多人数,那么选择第i个人数的话,dp(i)=dp(i-2)+ai,
如果不选择第i个人数的话,dp(i)=dp(i?1),这样得到转移方程dp(i)=max{dp(i-1),dp(i-2)+ai}。 注意,当k=0的时候特殊处理一下。 */ int main() {
while(scanf("%d%d", &n, &k) == 2) {
memset(cnt, 0, sizeof(cnt));
int score, ans = 0;
for(int i = 1; i <= n; i++) {
scanf("%d", &score);
cnt[score]++;
}
//特殊处理k=0的情况
if(k == 0) {
for(int i = 0; i <= MAX_SCORE; i++) {
if(cnt[i]) ans++;
}
}
else {
//共k份
for(int i = 0; i < k; i++) {
int m = 0;
//取得每一组 初始x为i 后面就是x+k x+2k x+3k ...
for(int j = i; j <= MAX_SCORE; j+=k) {
val[m++] = cnt[j];
}
dp[0] = val[0];
for(int j = 1; j < m; j++) {
if(j == 1) dp[j] = max(dp[0], val[j]);
else dp[j] = max(dp[j-2] + val[j], dp[j-1]);
}
ans += dp[m-1];
}
}
printf("%d\n", ans);
}
return 0;
}
/*
10 1
2 1 1 1 1 4 4 3 4 4
*/

6.观光铁路 0%

读不懂

网上搜到两份博客解析这道题:

https://blog.csdn.net/weixin_40839812/article/details/79769757

https://blog.csdn.net/BUAA_Alchemist/article/details/86768839#

本文参考至:https://www.cnblogs.com/flyawayl/

2017年蓝桥杯B组C/C++决赛题解的更多相关文章

  1. 2017年蓝桥杯B组C/C++决赛题目

    2017年第八届蓝桥杯B组C/C++决赛题目 点击查看2017年蓝桥杯B组C/C++决赛题解     1.36进制 对于16进制,我们使用字母A-F来表示10及以上的数字. 如法炮制,一直用到字母Z, ...

  2. 2018年蓝桥杯A组C/C++决赛题解

    2018年第九届蓝桥杯A组C/C++决赛题解 点击查看视频题解 点击查看2018年蓝桥杯A组C/C++决赛题目(不含答案) 1:三角形面积 画个图,求三角形面积,可以用外接长方形 - 其他多余区域面积 ...

  3. 2016年蓝桥杯B组C/C++决赛题解

    2016年第七届蓝桥杯B组C/C++决赛题解 2016年蓝桥杯B组C/C++决赛题目(不含答案) 1.一步之遥 枚举解方程,或者套模板解线性方程 #include<bits/stdc++.h&g ...

  4. 2015年蓝桥杯B组C/C++决赛题解

    2015年第六届蓝桥杯B组C/C++决赛题解 点击查看2015年第六届蓝桥杯B组C/C++国赛题目(不含答案)     1.积分之迷 三重循环 枚举A,B,C的值,如果满足两个条件:3个A + 7个B ...

  5. 2018年蓝桥杯B组C/C++决赛题解

    2018年第九届蓝桥杯B组C/C++决赛题解 点击查看2018年蓝桥杯B组C/C++决赛题目(不含答案) 1.换零钞 ok 枚举 设x表示1元钱的个数,y表示2元钱的个数,z表示5元钱的个数 x+21 ...

  6. 2018年蓝桥杯A组C/C++决赛题目

    2018年蓝桥杯A组C/C++决赛题目 2018年蓝桥杯A组C/C++决赛题解     1:三角形面积 已知三角形三个顶点在直角坐标系下的坐标分别为: (2.3, 2.5) (6.4, 3.1) (5 ...

  7. 2016年蓝桥杯B组C/C++决赛题目

    2016年第七届蓝桥杯B组C/C++决赛题目 点击查看2016年第七届蓝桥杯B组C/C++决赛题解 1.一步之遥 从昏迷中醒来,小明发现自己被关在X星球的废矿车里. 矿车停在平直的废弃的轨道上. 他的 ...

  8. 2018年蓝桥杯B组C/C++决赛题目

    自己的博客排版,自我感觉略好一点. 先放上题目. 点击查看2018年蓝桥杯B组C/C++决赛题目题解     1.换零钞 x星球的钞票的面额只有:100元,5元,2元,1元,共4种. 小明去x星旅游, ...

  9. 2015年蓝桥杯B组C/C++决赛题目

    2015年第六届蓝桥杯B组C/C++国赛题目 点击查看2015年第六届蓝桥杯B组C/C++国赛题解     1.积分之迷 小明开了个网上商店,卖风铃.共有3个品牌:A,B,C. 为了促销,每件商品都会 ...

随机推荐

  1. oracle数据库自动生成数据库表结构文档(亲测有效)

    import java.awt.Color; import java.io.FileOutputStream; import java.sql.Connection; import java.sql. ...

  2. gcc 4.9 编译安装 in Ubuntu 18.04(主要用于在无root权限下,进行更新系统 gcc 版本)

    gcc 4.9 编译安装教程,因为项目编译过程中,需要采用特定的gcc版本来进行编译,所以进行简要记录,进行备忘: 下载:curl -O -L https://mirrors.tuna.tsinghu ...

  3. new和delete创建和释放动态数组

    1.动态创建和释放一维数组 #include<iostream> using namespace std; int main() { int n; cin>>n; //分配动态 ...

  4. Keras保存模型并载入模型继续训练

    我们以MNIST手写数字识别为例 import numpy as np from keras.datasets import mnist from keras.utils import np_util ...

  5. 【翻译】spring-data 之JdbcTemplate 使用

    文档 Jdbc的使用 基础的代码结构: 一个Application作为入口.IUserRepository和UserRepository作为具体的实现.applicationContext.xml定义 ...

  6. 导出HTML5 Canvas图片并上传服务器功能

    这篇文章主要介绍了导出HTML5 Canvas图片并上传服务器功能,文中通过实例代码给大家介绍了HTML5 Canvas转化成图片后上传服务器,代码简单易懂非常不错,具有一定的参考借鉴价值,需要的朋友 ...

  7. C++入门到理解阶段二基础篇(4)——C++运算符

    目录 算术运算符(进行四则运算) 赋值运算符(表达式的值赋给变量) 比较运算符(表达是比较,返回一个真值或假值) 逻辑运算符(返回表格式的结果真或假) 位运算符 杂项运算符 C++ 中的运算符优先级 ...

  8. Bag of Tricks for Image Classification with Convolutional Neural Networks

    url: https://arxiv.org/abs/1812.01187 year: 2018 文中介绍了训练网络的一些 tricks, 通过组合训练过程的trick,来提高模型性能和泛化能力,以及 ...

  9. [转]探索ASP.NET Core 3.0 系列

    这是该系列的第一篇文章:探索ASP.NET Core 3.0. 第1部分-探索新的项目文件Program.cs和通用主机(本文) 第2部分-比较ASP.NET Core 3.0模板之间的Startup ...

  10. winform批量更新数据_长时间的执行会导致界面卡死

    前言:使用winform触发一个事件后执行的代码,如果耗时非常长,则会导致窗口界面假死!  本人最近通过winform窗体执行一项:需要批量更新一批数据库的数据的操作的任务时,由于数据量达到百万级别, ...