问哥在最后30分钟才有空进入比赛,发现满分选手只有两位,就知道大家又遇到坑了。。。其中两道题的数据都多少有点问题。不得不佩服那两位在这种情况下还能拿满分的选手,等到他们分享解题报告后,问哥再来更新代码吧。
第一题:鬼画符门莲台争夺战
鬼画符门莲台争夺战!虽然鬼画符门是一个三流门派,但是近期为了改善宗门弟子质量,特意引进了进化莲台。部分精英弟子会自己独占一块区域,或者几个精英弟子一块占领一块区域,他们占领的区域普通弟子不可以再占领。小艺作为普通弟子想知道自己还能占领哪些地方。莲台区域以1开始,由小到大编号表示。
输入:第一行两个整数n、m,分别代表弟子数量和莲台数量(1到m),下面n行表示每个弟子占领的莲台左、右莲台编号。
输出:如果无可用莲台,输出0,否则,输出可用莲台数量,然后在第二行输出莲台编号。
分析
不记得示例了,不过不影响,反正也是水题。题意翻译过来就是,有连续整数组成的集合(1到m),删除n次数据,问剩下元素数量及内容。使用python的集合操作即可。
参考代码
n, m = map(int, input().strip().split())
total = set(range(1,m+1))
for _ in range(n):
l, r = map(int, input().strip().split())
total.difference_update(set(range(l, r+1)))
if len(total)==0:
print(0)
else:
print(len(total))
print(*total)
第二题:津津的储蓄计划
津津的零花钱一直都是自己管理。每个月的月初妈妈给津津 300 元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上 20% 还给津津。 因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈给的零花钱后,如果她预计到这个月的月末手中还会有多于 100 元或恰好 100 元,她就会把整百的钱存在妈妈那里,剩余的钱留在自己手中。例如 11 月初津津手中还有 83 元,妈妈给了津津 300 元。津津预计 11 月的花销是 180 元,那么她就会在妈妈那里存 200 元,自己留下 183 元。到了 11 月月末,津津手中会剩下 3 元钱。 津津发现这个储蓄计划的主要风险是,存在妈妈那里的钱在年末之前不能取出。有可能在某个月的月初,津津手中的钱加上这个月妈妈给的钱,不够这个月的原定预算。如果出现这种情况,津津将不得不在这个月省吃俭用,压缩预算。 现在请你根据2004年1月到12月每个月津津的预算,判断会不会出现这种情况。如果不会,计算到2004年年末,妈妈将津津平常存的钱加上20%还给津津之后,津津手中会有多少钱。
示例1 示例2 输入 290
230
280
200
300
170
340
50
90
80
200
60290
230
280
200
300
170
330
50
90
80
200
60输出 -7 1580
分析
本来没啥好分析的,这不就是初中数学应用题嘛,按照题目描述的一句句写代码即可,而且原题在此。但是——上次问哥还说CSDN的数据测试可能不如洛谷的严格,这么快就被打脸——同样的代码在洛谷顺利pass,在CSDN的周赛却只能通过一半的测试数据。思考许久仍找不到到底miss在哪里,等到满分同学分享代码后问哥再来更新吧。
参考代码
budgets = [int(input()) for _ in range(12)]
start = saving = 0
for i in range(12):
start += 300 - budgets[i]
if start < 0:
print(0-i-1)
break
else:
saving += start//100
start %= 100
else:
print(saving*120+start)
第三题:多边形的面积
给出一个简单多边形(没有缺口),它的边要么是垂直的,要么是水平的。要求计算多边形的面积。 多边形被放置在一个 XY 的卡笛尔平面上,它所有的边都平行于两条坐标轴之一。然后按逆时针方向给出各顶点的坐标值。所有的坐标值都是整数(因此多边形的面积也为整数)。
分析
纯纯的数学题,属于那种“知道公式很快就能写出来”的题目,和代码基本没什么关系。
n个顶点组成的多边形面积计算公式为:
由于横纵坐标交叉相乘再相减,又可以形象地称之为“鞋带公式”,保证你看了就记住了。
参考代码
n = int(input())
vector = []
for _ in range(n):
vector.append([int(i) for i in input().strip().split()])
a = sum(vector[i][0]*vector[i+1][1] for i in range(n-1))
b = sum(vector[i][1]*vector[i+1][0] for i in range(n-1))
a += vector[0][1]*vector[-1][0]
b += vector[0][0]*vector[-1][1]
print(abs(a-b)//2)
第四题:小桥流水人家
在n*m的地图上,存在一个喷水点,如果相邻的位置低于有水的地方,水就能流到相邻的某位置(即该格子需要其上下左右的格子海拔都比自身高的封闭图形才可以积水)。已知各个格子的海拔高度,求积水的最大覆盖个格子数。
示例:
示例1 示例2 输入 3 6
3 3 4 4 4 2
3 1 3 2 1 4
7 3 1 6 4 1
3 4
3 3 4 5
3 1 2 2
9 3 1 6
输出 5 1
分析
本期最坑的题目来了。其实这也是每日一练里出现过的题目,但是,题目组做了点修改(问哥认为是很自以为是的修改),删去了喷水点的坐标,但却并未修改题干,也未增加对示例的说明,导致大家对题意各种猜测。问哥先给出之前每日一练中使用的解法,然后再讨论一下题目组的修改意图。
在修改之前,这是一道经典的深搜题,大家在其他网站或多或少应该都见过,就是每天或每过一段时间出水点(或其他什么东东)就会向上下左右四个方向(也有八个方向)蔓延,然后问一段时间后符合条件的坐标点有多少。只要从出水点的位置分别向四个方向深度搜索,如果符合条件(①未出界;②未被水覆盖;③海拔比出水点低),则将这个位置标记为被水覆盖的点,然后继续以这个点为中心向上下左右递归搜索。然后,最后统计一下有哪些位置被水覆盖即可。
参考代码
n, m, x, y = map(int, input().strip().split())
vector = []
for _ in range(n):
vector.append([int(i) for i in input().strip().split()])
def dfs(x,y,center):
for a,b in co:
x0, y0 = x, y
x0 += a
y0 += b
if 0 <= x0 < n and 0 <= y0 < m and water[x0][y0] = =0 and vector[x0][y0] < center:
water[x0][y0] = 1
dfs(x0,y0,center)
water = [[0]*m for i in range(n)]
water[x-1][y-1] = 1
co = ((0,-1),(0,1),(1,0),(-1,0))
center = vector[x-1][y-1]
dfs(x-1,y-1,center)
result = sum(sum(i) for i in water)
print(result)
但是,这只是针对之前每日一练中出现的、有明确指出出水点的位置的情况。而出现在本周赛的题目里是没有给出出水点位置的,那出题组是什么意图呢?由于题目说得并不清楚,对示例也并未加以说明,所以问哥猜测有以下三点:
- 出水点默认在中心位置(可能较小)
- 默认四周水会流走,不会形成积水(可能性大)
- 结果里被水覆盖的是积水体积,而不是格子个数(可能性大)
根据第一个猜测,如果出水点位置在中心的话,两个示例就都能满足了(示例一中出水点是第二行第三列,海拔3,示例二中出水点是第二行第二列,海拔1)。
通过上面的代码计算,可以得出被水覆盖的位置如上图中橘色点的位置。但是,这只是猜测,据此修改的代码也只能通过一半的测试数据(运气),所以这个猜测并不十分靠谱,而且如果出题人真的是因为这个理由而把出水点的位置去除的话,估计会被骂到死。
而根据第二个猜测,既然题目问的是积水,那我们就想想,是不是被水“流过”的格子不算“积水”(文字游戏)?这样一来,默认外面一圈存在最低点,所以不管出水点在哪儿,只要和外面接通了,水就都流走了,而剩下的就都是能够形成积水的洼地?如下图所示,不管出水点在哪,最终都只有图中的橘点形成积水。
但是,如果这样理解的话,示例一的答案就不正确了。
所以,问哥不得不在此再加上第三个猜测,那就是要求的并不是格子的个数,而是覆盖积水的总体积。比如上图中,第一个积水点(橘点)的高度是1,和旁边最低的高度3(可以形成积水的高度)的落差是2,右边两个积水点的高度是2和1,和3的落差分别是1和2,这样一来,2+1+2=5,答案就对上了。而同样的猜测也适用于右边示例二,积水点的高度是1,和右侧可以形成积水的最低高度2的落差为1,所以答案是1。
那,这是不是正确的猜测呢?鬼知道!
等问哥胡乱猜测到这里的时候,时间已经所剩不多,再也没心情调试了,索性点了交卷。这已经和写代码无关了——连需求是啥都没搞清楚,乱试是没有意义的。等着看满分大佬的分享,再回来更新吧。
问哥忍不住吐槽——虽然官方未必会看到,看到了也未必会改——既然改了题目,就要好好说明题意,避免错误解读,还要多找几个人评测一下,看看会不会产生误解。大家来练的是解题思路和代码的熟练度,而不是来考中文的阅读理解。还需要去猜测出题人的意图,这样的比赛让人觉得毫无意义。