(蓝桥杯备战)(数位bfs)与完全二叉树,st表
蓝桥杯第十一届校内模拟赛的所学
3. 叶节点数
【问题描述】
一棵包含有2019个结点的二叉树,最多包含多少个叶结点?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分
对任何一棵二叉树:度为0的结点数(即叶节点) = 度为2的节点数 + 1; 当二叉树的总个数为奇数时,此二叉树"无度为1"的结点 当二叉树的总个数为偶数时,此二叉树"只有一个度为1"的结点 设:度为2的结点数为n个 度为0的结点数+度为1的结点数+度为2的结点数=N ( n+1 )+(n)=2019 解得:n=1009 所以 : 度为2的结点数:1009个 度为1的结点数:0个(因为2019是奇数,所以此二叉树没有度为1的结点) 度为0的结点数(叶子节点数):1010个(等于度为2的结点数+1)
##编程题(二)
问题描述
在数列 a[1],a[2],…,a
中,如果对于下标 i,j,k 满足 0<i<j<k<n+1 且 a[i]<a[j]<a[k],则称 a[i],a[j],a[k] 为一组递增三元组,a[j]
为递增三元组的中心。
给定一个数列,请问数列中有多少个元素可能是递增三元组的中心。
输入格式
输入的第一行包含一个整数 n
。
第二行包含 n
个整数 a[1],a[2],…,a
,相邻的整数间用空格分隔,表示给定的数列。
输出格式
输出一行包含一个整数,表示答案。
评测用例规模与约定
对于 50
的评测用例,2<=n<=100,0<=Num<=1000 。
对于所有评测用例,2<=n<=1000,0<=Num<=10000
当然也可以用 ST 表把复杂度优化为 O(nlogn)
以后学st表
。
代码如下:
#include <bits/stdc++.h> #define MAXN 10007 #define INF 0x3f3f3f3f using namespace std; int n,ans,t1[MAXN][20],t2[MAXN][20]; inline void init() { for (int j=1;j<=log2(n);j++) for (int i=1;i<=n-(1<<j)+1;i++) { t1[i][j]=min(t1[i][j-1],t1[i+(1<<(j-1))][j-1]); t2[i][j]=max(t2[i][j-1],t2[i+(1<<(j-1))][j-1]); } } inline int q1(int l,int r) { if (l>r) return INF; int t=log2(r-l+1); return min(t1[l][t],t1[r-(1<<t)+1][t]); } inline int q2(int l,int r) { if (l>r) return -1; int t=log2(r-l+1); return max(t2[l][t],t2[r-(1<<t)+1][t]); } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&t1[i][0]),t2[i][0]=t1[i][0]; init(); for (int i=1;i<=n;i++) if (q1(1,i-1)<t1[i][0] && q2(i+1,n)>t1[i][0]) ans++; printf("%d",ans); }
##编程题(三)
问题描述
一个正整数如果任何一个数位不大于右边相邻的数位,则称为一个数位递增的数,例如 1135
是一个数位递增的数,而 1024
不是一个数位递增的数。
给定正整数 n
,请问在整数 1 至 n
中有多少个数位递增的数?
输入格式
输入的第一行包含一个整数 n
。
输出格式
输出一行包含一个整数,表示答案。
评测用例规模与约定
对于 40%
的评测用例,1<=n<=1000。
对于 80% 的评测用例,1<=n<=100000。
对于所有评测用例,1<=n<=1000000
。
——————————————————————————————
#include <bits/stdc++.h> int n,ans=0; using namespace std; void dfs(int num) { for (int i=num%10?num%10:1;i<=9;i++) if (num*10+i<=n) ans++,dfs(num*10+i);//几行代码精辟 } int main() { scanf("%d",&n),dfs(0); printf("%d",ans); return 0; }
我既没看出来这是dp也没看出是深度搜索
##编程题(五)
问题描述
小明想知道,满足以下条件的正整数序列的数量:
第一项为 n
;
第二项不超过 n
; 从第三项开始,每一项小于前两项的差的绝对值。
请计算,对于给定的 n
,有多少种满足条件的序列。
输入格式
输入一行包含一个整数 n
。
输出格式
输出一个整数,表示答案。答案可能很大,请输出答案除以 10000
的余数。
评测用例规模与约定
对于 20%
的评测用例,1<=n<=5。
对于 50% 的评测用例,1<=n<=10。
对于 80% 的评测用例,1<=n<=100。
对于所有评测用例,1<=n<=1000
。
——————————————————————————————
50
分的做法就是直接暴力 dfs,首先敲了如下代码,再进行优化。
这东西能过%50,但是老子不会!!!
#include <bits/stdc++.h> #define MAXN 1007 using namespace std; int ans,a[100007]; int dfs(int st) { ans++; int cha=abs(a[st]-a[st-1]); for (int i=1;i<cha;i++) { a[st+1]=i,dfs(st+1); } } int main() { int n; scanf("%d",&n),a[1]=n; for (int i=1;i<=n;i++) { a[2]=i,dfs(2); } printf("%d",ans); return 0; }
靠!离省一太远了这东西我根本不会,我一天天都在干什么
#include <bits/stdc++.h> #define MAXN 1007 #define mod 10000 using namespace std; int ans,f[MAXN][MAXN]; int dfs(int p1,int p2) { if (f[p1][p2]) return f[p1][p2]; f[p1][p2]=1; for (int i=1;i<abs(p1-p2);i++) f[p1][p2]+=dfs(p2,i),f[p1][p2]%=mod; return f[p1][p2]; } int main() { freopen("","w",stdout); printf("int table[1001]={0,"); for (int n=1;n<=1000;n++) { ans=0; for (int i=1;i<=n;i++) ans+=dfs(n,i),ans%=mod; printf("%d",ans); if (n!=1000) printf(","); } printf("}"); return 0; }
##编程题(六)
问题描述
小明要组织一台晚会,总共准备了 n
个节目。然后晚会的时间有限,他只能最终选择其中的 m
个节目。
这 n
个节目是按照小明设想的顺序给定的,顺序不能改变。
小明发现,观众对于晚上的喜欢程度与前几个节目的好看程度有非常大的关系,他希望选出的第一个节目尽可能好看,在此前提下希望第二个节目尽可能好看,依次类推。
小明给每个节目定义了一个好看值,请你帮助小明选择出 m
个节目,满足他的要求。
输入格式
输入的第一行包含两个整数 n
, m
,表示节目的数量和要选择的数量。
第二行包含 n
个整数,依次为每个节目的好看值。
输出格式
输出一行包含 m
个整数,为选出的节目的好看值。
评测用例规模与约定
对于 30%
的评测用例,1<=n<=20;
对于 60% 的评测用例,1<=n<=100;
对于所有评测用例,1<=n<=100000,0<=value<=100000
。
——————————————————————————————
一个贪心题。
由于在小明的策略下一定是要选择当前能选中好看值最大的节目,所以每次选择就是在当前能选的节目中找好看值最大的,不考虑之后如何选择。
当然小明至少要给未选节目们留最小的选择空间,不然就无法选够 m
个节目,
于是发现当前能选的节目是一个区间,比如小明还有 p
个节目要选,共 n 个节目,上次选了 k
号节目。
那么他的本次选择节目区间就是 [k+1,n−p+1]
,如此迭代,就可以确定每次的选择。
对于 60
分来说每次在区间内容找最大值即可,优化的话就是加入记录了最大值和最大值来源 ST
表(我们同时关心这两个值)。
还要注意如果区间上有多个值相等,应该保留位置靠前的一个(贪心)。
有是St表靠必须干了
#include <bits/stdc++.h>
#define MAXN 100007
using namespace std;
struct Seg { int val,id; }st[MAXN][20];
int n,m,k,v[MAXN];
inline void init() {
for (int j=1;j<=log2(n);j++)
for (int i=1;i<=n-(1<<j)+1;i++) {
if (st[i][j-1].val<st[i+(1<<(j-1))][j-1].val)
st[i][j]=st[i+(1<<(j-1))][j-1];
else st[i][j]=st[i][j-1];
}
}
inline Seg q(int l,int r) {
int t=log2(r-l+1);
if (st[l][t].val>=st[r-(1<<t)+1][t].val) return st[l][t];
else return st[r-(1<<t)+1][t];
}
int main() {
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&st[i][0].val),st[i][0].id=i;
init(),k=1;
for (int i=m;i>=1;i–) {
Seg now=q(k,n-i+1);
k=now.id+1,printf("%d ",now.val);
}
return 0;
}
- 点赞
- 收藏
- 分享
- 文章举报
- 【备战蓝桥杯】【递归】【C语言】【ALGO-20算法训练 求先序排列】
- 蓝桥杯BFS 移动方格的问题
- 【蓝桥杯】 算法提高 学霸的迷宫(深度优先搜索、BFS)—— 酱懵静
- 蓝桥杯备战-字母图形
- 蓝桥杯 ALGO-98 算法训练 数位分离
- 假期备战蓝桥杯stm32学习笔记(三)
- 【备战蓝桥杯】USACO--> Beads 2.0
- 【备战蓝桥杯】USACO--> barn (终结)
- 蓝桥杯 取数位(第八届第五题)
- 蓝桥杯备战 字符串和日期笔记
- 2013 蓝桥杯C/C++本科B组 带分数(牛逼库函数)(备战LQB)
- 蓝桥杯-算法提高 学霸的迷宫(BFS-倒向追踪输出移动方向)
- 蓝桥杯_算法提高_学霸的迷宫(BFS方法)
- 蓝桥杯 取数位
- 【备战蓝桥杯】【递归】【C语言】【ALGO-11算法训练 瓷砖铺放】
- 第六届蓝桥杯决赛真题 04 穿越雷区(dfs || bfs)
- C++ - 蓝桥杯 - 算法提高 学霸的迷宫 (bfs+记录路径)
- 蓝桥杯备战-01字串
- 备战蓝桥杯(真题)第七届第六题“凑算式”
- 蓝桥杯 剪邮票 (DFS+BFS)