去年打过一次蓝桥杯,之前的题型都是十个题目,而且前面的很简单,这次直接8个题目,一开始我以为捡了便宜,没想到每个题都很难,而且机房电脑很古董卡了十分钟,旁边的人打字又快又响,有点思路他一打字思路就没了。只做了A,C,D,E,F题,F题只有半成品代码,过多少看运气,差不多30分将近40分的样子,不知道还有没有省一了,估计很难,但是看这套题目,大多数人只能写起第一题,第二题可能只有10%以内的人写的起来,第三题比较简单,40%的人写得出来,第四题考察数据结构和树状dp,很难,可能也是10%以内的人写的出来,第五题稍微简单,但是70%的人不会使用二分,要超时,第六题可能一大半没做,一大半只能通过样例和n<50的例子,第七题也很难,写得出来的人很少,就算有时间交暴力,后面的题目肯定没时间看,前面的题目肯定没做完,第八题在考场上先做完前面的题目并且在古董电脑+嘈杂环境当中读懂并且AC的人,只有可能是国一+的水平,欢迎大家在评论区讨论自己做的题目和估分,我会及时回复。
此处只提供思路,和时间复杂度,第八题看不懂。
此题先使用数组存储每个数字的笔画,然后使用循环得到区间的每个日期,再去判断即可。
此题有多种方法:
1.搜索,使用深度优先搜索:直接在棋盘上面布局,当棋子走到(i,5),(5,j)的时候分别对12种情况进行讨论,同时,如果白棋大于14,则退出搜索.
2.状态压缩+广度优先搜索:用一个int a来存储一个25位的数字,黑棋标注为1,白棋子标注为2,再进行搜索即可。
此题使用的是前缀数组和的方法来求解,如果有闲心可以加二分,时间复杂度为O(logn+nlogn)不加二分的情况时间复杂度为O(n+nlogn)都能过:
此处讨论不加二分的情况:
首先给出一个向量vector<array<int,2>> peo;用来读取数据,存储人训练一次的金币数量,训练次数;然后使用sort(peo.begin(),peo.end(),s);来按照训练次数从小到大排序,接下来处理peo[i][0],用一个for循环执行以下操作:peo[i][0]+=peo[i-1][0],那么可以知道:现在peo第i个元素第0个位置存储的是训练次数排好序之后从第一个元素到第i个元素的求和,那么,已知训练次数是单调递增的,那么直接从第一个开始遍历,首先需要一个min1 = 999999999999;来存储最小值,最后得到以下递推公式:if((peo[n-1][0]-peo[i][0]>s)i++;
最终当i停止之后,最后从第i个元素开始遍历:首先先初始化sum = s*peo[i][1],然后对后面剩余的钱进行求和,得到答案。
这道题目对选手对树的理解要求及其的高,我考试没做这道题,我们学校机房太烂了,并且旁边的哥们是个急性子,很搞人。第一,先输入信息,得到两个树的大小,两个树的节点权值,两个树的连接方法;接下来,使用:
unordered_map<int,set<int>>position;//对于第一个树当中出现的一个权值,在第二个树当中寻找这个权值的节点,只需要对第二个树遍历一次就可以了。
unordered_map<int,int>fa1,fa2;//分别用于存储树1和树2的父节点,分别遍历一次就出来了
unordered_map<int,int>ans;//表示第二个树第i个节点的答案最大值
int max1=0;//用来寻找最大结果
首先对ans当中每个第二棵树的节点赋值为1:
那么开始遍历第一颗树:
遍历到i节点的时候,首先去看i节点的数字在第二棵树的哪些节点出现了,然后分类讨论:
if i == 1 : 此时不用讨论父亲节点,直接赋值为1就可以了
else : 如果这两个数字的父节点相同,那么ans[第一个树的第i个节点的权值] =
max(max(ans[第一个树的第i个节点的权值] ,1),ans[father]+1);
接下来需要对max1进行更新:max1 = max(max1,ans[第一个树的第i个节点的权值] );
对于随机数据,整个过程的时间复杂度为O(n+m),对于特殊数据:假如两棵树当中一个数字出现了很多次,那么时间复杂度为O(n*m),但是题目条件当中说一定不存在相同的节点,那么时间复杂度为O(n+m)
不知道为什么主办方不把这道题目放在C题,我觉得前面两个题目比这个难,很多人都做不来的。
这道题很简单,如果不用二分,可以通过30%的测试点,如果使用二分,可以通过全部测试点:
你要做的就是对于k来二分(类似于前面的青蛙过河算法),其他的我就不说了。
使用一个vector<int>tim;来存储每个出现过的数字出现的次数O(n)
使用素数筛寻找100000以内的所有素数,然后得到每个数字的所有因数,
存于unordered_map<int,vector<int>> yin;O(n(loglogn+sqrt(n)))
继续对yin进行处理:对于从未出现过的因数进行删除;
那么现在需要找到不同的两组数据使得满足题目的条件。
对于被因数字有以下情况:
两个数字相同
两个数字一大一小但是其中一个为另外一个的公约数
都不是
对于因数有以下的情况:
因数相同
因数不相同
因数和被因数之间的关系:
相同
不同
那么现在需要推出公式,将时间复杂度缩短到O(n*sqrt(n)):
假如第一个被因数出现了m次,第二个被因数出现了n次,首先使用二元组(a,b),其中a表示一个因数大小,b表示其出现的次数,对于这种情况,可以得到公式为
times = m*n*((sum(ai))*(sum(bi))-sum[aj])
假设两个被因数相同:
times = m*(m-1)*((sum(ai))*(sum(bi))-sum(aj))
两个数字一大一小但是其中一个为另外一个的公约数:
times = m*n*((sum(ai)-1)*(sum(bi))-sum[aj])
or
m*n*((sum(ai))*(sum(bi)-1)-sum[aj])
最终算法的时间复杂度可以稳定在O(n*sqrt(n))
为了解决这个问题,我创造了一种结构体:
点i最近属于哪个节点
节点i的父节点
节点定义:分支大于等于2的点
那么首先需要从节点1进行往下的遍历,存储从节点1到节点i各种糖果出现的次数,存于vector<vector<int>> food。
同时,更新每个节点的父节点,以及所属于的最近的节点。
然后对于q个问题当中的每个问题:
1.寻找公共最近节点,遍历其最近的节点,以及其最近节点的所有最近节点,最后会回到节点1,对两个位置同时进行此操作,然后从后往前查找二者开始分叉的位置k,此位置乃公共最近节点,那么从公共节点到节点i和从公共节点到节点j的路径就是最短路,糖果的数量分析:
food_route = food[k]-food[i]+food[k]-food[j]最后再遍历food_route当中有多少种糖果就行了
我读不懂题目,求大佬题解
总的来讲,这次比赛比以往任何一届都难,因此蓝桥杯有变难的趋势,这是一件好事情,说明蓝桥杯A组正在从水的正式比赛向正式的正式比赛转型,未来的求职当中会更加的认可蓝桥杯的证明。总有人说这次没有dp,那是因为这次考察的dp比较混杂,需要结合对不同数据结构的理解,来做,不是简单的最短路,区间dp,树状dp,LCD等算法可以解决的,仍然需要大量刷题来获得经验才能在短短的四个小时以内完成尽可能多的题目。