2018年第九届蓝桥杯C/C++省赛A组题解
第一题:
题意:就是求一个,首项为1,等比为1/2的等比数列的前二十项之和
答案:就是2^20-1/2^20
第二题:
题意:求整个二十世纪总共有多少个星期一
求解过程:当时灵机一动,打开电脑日历,查看了20世纪第一天是星期一(哈哈),然后算出整个二十世纪有25个闰年,所以总天数就是(365*100+25)/7 = 5217天。
第三题
题意:求解给定的数相乘得到的数末尾有多少个零
求解过程:算出这些数中一共包含多少个2,多少个5,然后取最小值就可以了,答案我记得是31。
第四题
题意:问某个数M是第多少个3,5,7构成的数
求解过程:这个题目跟杭电1058的丑数问题很像。
附上链接:http://acm.hdu.edu.cn/showproblem.php?pid=1058
如果直接采用暴力求解验证的话,是需要花费很长时间的,采用动态规划的思路去进行求解,转移方程为dp[i] = min(dp[p3]*3,dp[p5]*5,dp[p7]*7)。初始时,p3=p5=p7=0,dp[0]=1,
当时我写的代码是这样的:
for(int i=1;i<=2020;i++) { if(dp[i]==dp[p3]*3) p3++; if(dp[i]==dp[p5]*5) p5++; if(dp[i]==dp[p7]*7) p7++; if(dp[i]==M){printf(“%d\n”,dp[i]); break;} }
我记得当时打印出来的结果好像是1905.
第五题:代码填空
题意:输出一个贼SB的图形
求解过程:当时记得那个函数里面的n就是表示的切分为几份,直接提交 size/3.
编程题1:时差问题
题意:一架飞机从一个地方飞到另一个地方(可能跨时区),再飞回原地方。飞机往返飞行时间相等。
求解过程:
起程:起飞时间start1(时区1)-----降落时间end1(时区2)
返程:起飞时间start2(时区2)-----降落时间end2(时区1)
首先将各个时间均转换为秒,统一计算。
其实不需要知道具体的时区差,只需要计算((end2-start1)-(start2-end1))/2即可。
相当于计算离开原地点,再回到原地点的时间差减去在目的点停留的时间,再除以2得到答案。
需要注意的是,题目中给定的时间都是当天时间,就需要根据end1和start2以及是否次日到达或者第三日到达,对时间进行调整。
编程2:立方体进攻
题意:给定一个N*M*K的立方体,每个单元是一个数,受到P次进攻,每轮次给定xi1~xj1,yi2~yj2,zi3~zj3,m,凡是属于这些行列竖的数均受到一个m的伤害(即减去m)。求解在第几次进攻中,立方体中有数小于0出现。
求解过程:当时其实想到了是用一个三维树状数组的区间修改过程,但是感觉写起来比较麻烦,就用了暴力解。实属下策,等到题目放出来的时候再求解一波。
编程3:冰川融化
题意:给定一个字符矩阵,‘*’代表水,‘#’代表陆地,连着的‘#’构成一片岛屿。但是一块陆地上下左右只要有一块水,这个陆地就会被融化。求解最后会剩下多少块岛屿。
求解过程:典型的记忆化搜索。
先对整个字符矩阵扫一遍,将*标记为已访问,如果#周围有*也将其标记为已访问,最后对矩阵进行记忆化搜索,搜索多少次,就表明还有多少块岛屿。
编程题4:三个数之和是K的倍数
题意:在给定的数组中,求出三个不同数的组合,使得其之和最大且为给定数M的倍数。
求解过程:背包问题
首先将数组扫一遍,将每个数余M得到的余数作为这个数的重量,本身的数作为其价值。问题就转换为给定N个货物的重量和价值,求解将三个货物能将容量为M的背包恰好填满,且得到的价值最大。动态转移方程为:dp[i][k] = max{ dp[i-ai][k-1],dp[i][k]}。
其中dp[i][k]表示为容量为i时,当前货物为k时能得到的最大收益。初始化时,需要将dp数组初始为负无穷大,且dp[0][0] = 0.
编程题5:最小标准差
题意:n个人拥有不同的钱,需要共同付一笔M元的账单,求解一种付钱的方案:使得最后付钱的方案标准差最小。
求解过程:
当时实在没有比较好的思路,直接暴力求解了一波30%的分,需要进一步研究~~~