2017年蓝桥杯B组C/C++决赛题解
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++决赛题解的更多相关文章
- 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:三角形面积 画个图,求三角形面积,可以用外接长方形 - 其他多余区域面积 ...
- 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 ...
- 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. 为了促销,每件商品都会 ...
随机推荐
- filebench - File system and storage benchmark - 模拟生成各种各样的应用的负载 - A Model Based File System Workload Generator
兼容posix 接口的文件系统中我们不仅要测试 posix 接口是否兼容.随机读,随机写,顺序读,顺序写等读写模式下的性能.我们还要测试在不同工作负载条件下的文件系统的性能的情况:Filebench ...
- DWR服务器推送技术
参考博客:https://blog.csdn.net/Marksinoberg/article/details/55505423 下载Dwr.jar文件 到官网http://directwebremo ...
- idea安装以及使用
1. 简介1.1 IDEA 全称 IntelliJ IDEA,是java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手.代码自动提示.重构. J2EE ...
- JVM-0-JVM知识体系
- Codeforces Round #603 (Div. 2)
传送门 感觉脑子还是转得太慢了QAQ,一些问题老是想得很慢... A. Sweet Problem 签到. Code /* * Author: heyuhhh * Created Time: 2019 ...
- Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) D2. Optimal Subsequences (Hard Version) 数据结构 贪心
D2. Optimal Subsequences (Hard Version) This is the harder version of the problem. In this version, ...
- ACL学习
H3C ACL主要有三种: 标准ACL: 2000-2999,基于源IP地址分配: 高级ACL:3000-3999,基于源目IP地址分配,报文优先级等三.四层信息: 二层ACL:4000-4999,基 ...
- 利用Python进行数据分析-Pandas(第一部分)
利用Python进行数据分析-Pandas: 在Pandas库中最重要的两个数据类型,分别是Series和DataFrame.如下的内容主要围绕这两个方面展开叙述! 在进行数据分析时,我们知道有两个基 ...
- Disruptor系列(二)— disruptor使用
本文译自Dirsruptor在github上的wiki中文章:Getting Started 获取Disruptor Disruptor jar包可以从maven仓库mvnrepository获取,可 ...
- 链表中删除倒数第K个节点
问题描述 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 问题分析与解决 从问题当中,我们只能得到一个链表和要删除的第K个节点的信息,于是就有以下思路:如 ...