2018上学期程序设计实践考试总结

这个博客不再更新,新博客地址请戳

算是有那么一点点遗憾的,考砸了,状态很差,该出的题没有出。
达成成就:做不到4题就退队flag秒破。

考试结束后和岑巨说,自己每次到了比较重要的比赛或者考试的时候,总会有点失眠。
希望到区域赛的时候能克服一下吧,精力不足很致命啦。
(然后谢大神补刀:BB这么多干嘛,你个菜逼(orzorz

好了下面主要是做题的过程和思路。


流水账
开场看A,发现见过,但是忘记怎么写了,于是跳B;
看B,看不懂,跳C;
C可做,(思路见下面),敲之,TLE,剪枝后ac;
然后再开D,可做,(思路在下面),敲之wa,找不到bug所以弃了;
看E,暂时没思路;
看F,可做,但是A显然比F简单,回过头做A;
A题过了之后,E题不想开,F题无限wa,B题不会推,欢声笑语中GG退队。


A思路:
首先记录一下字符串中,各个字符出现的次数,找到出现次数最多的那个字符出现了多少次,设为cnt吧。
那么,如果 cnt+p<=n ,该串的答案ans一定是cnt+p
否则,假设多余了pp个操作,我可以拿这pp个操作随便换,最后一步换到需要的字符,那么ans=n
有一个例外,比如 s=“aaa” p=1 ,这个情况下,答案为2,而不是3。
可以归纳为:当串中只有一种字符,并且p=1时,ans=n-1

这题的出题人岑巨已经回家躲着了哈哈哈哈哈。。。


B思路:
首先更新一下最高赔率的值,赢的赔率为w,平局赔率为d,输的赔率为l,由于一定要赢,三个都得买。
那么,根据赔率:
买1/w元的赢,如果中了可以得到1元;
买1/d元的平,如果中了可以得到1元;
买1/l元的输,如果中了可以得到1元;
那么最后无论如何我都能得到1元。

如果**(1/w+1/d+1/l)<1**,说明我花费小于收获。
我不管,这题我得甩锅给没睡好。


C思路:
根据题意一步一步来便可,看到数据范围,字符串长度等于200,不妨直接枚举一下获胜一局需要多少积分,
然后枚举一下赢得多少局算获胜。容易知道需要的积分的范围可以设为[1,len],那么一共最多能玩多少局呢?
这里一开始我写的[1,len]局,超时了。
剪枝:一局需要i积分,那么满足i*j<=len,区间可以修改为[1,len/i]。
至于暴力枚举,就不多说了。


D思路:
栅栏有横竖两种,我们可以从输入中统计一下每个横向的栅栏能够阻止多少对猪,每个纵向能够阻止多少对猪。
那么,如果这根栅栏有贡献了,一定要算进去。

如果给的栅栏数足够了,直接输出答案。如果给的不够,那么直接对贡献排序,把栅栏建在贡献高的位置便可。

个人认为CD应该放在AB的位置。难度较之简单一丢丢吧。


E思路:
因为是有向边,要从各个点到达x,又要回到各个点去,
不妨从x点正向和反向跑2次dijkstra最短路,貌似要加堆优化
也就是建2个邻接表,一个表存正向边的图,一个表存反向边的图,二者最短路相加,
找到最大值便可。


F思路:
动态规划或者记忆化搜索都能做。
dp[i][j]表示对[1,i]这个区间,拆分为j段,那么,
dp[n][m]就代表对区间[1.n]拆分为m段的结果。
如何递推呢?
首先初始化dp数组,令所有的dp[i][j]=-inf
(考试的时候我初始化为0了,如果要初始化为0,到时候的边界就要特别注意了。不如直接初始化-inf)

for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
		for(int k=1;k

dp[k][j-1]表示区间[1,k]划分j-1段的最大值。
dp[i][j]可以由dp[k][j-1]转移而来。转移方程如上。


没有事后诸葛亮啦,及时总结一下总是有好处的叭。
下次再遇到A题这出题人我会替大家收拾他的(岑巨我说着玩的您别当真…)


经验:
1.保证好睡眠
2.卡题要开新题,尤其是个人赛没有人给你debug
3.提升各方面奇淫姿势


溜了溜了~

你可能感兴趣的:(XTU—程序设计实践网站)