个人总结:
本周算是比较坎坷的一周,本来想着一步到位速战速决DFS和DP,发现被暴扣了一顿(orz)于是转战复习了并查集(简单难度)与排序和所有的暴力枚举(发现上周有漏的)这三个部分的知识和对应的真题。本次笔记主要是记录排序相关的赛题,并查集没刷完,后者一部分涉及dfs和dp内容的交叉部分,如果不涉及却又太简单了,所以本周笔记主要记录我发现的一些比较有趣和有价值的排序赛题,和一部分的暴力枚举赛题
暴力枚举:
兑换硬币(填空题):
第一题比较简单但比较考验读题
我们要捕捉到两个信息:
一个是只有新的硬币能换成老的;第二个关键在于面值为i的硬币它的个数为sumi,根据这些我们可以采用遍历的方式来解决这个问题即可。
result = [0 for i in range(4047)]
for i in range(1, 2024):
for j in range(i+1, 2024):
result[i+j] += i # 此处不能为1,因为这里个数也为i
print(max(result))
日期问题:
此题较为复杂第一步,我们应当放在如何针对年份月份日期进行排列,好在给定了我们日期的范围在1960~2059,所以我们可以通过年份末尾为60这个阈值来判断我们的年份所处的世纪,这样我们就完成了第二步,最后我们需要用到datetime库来创建一个日期对象。最后我们将数据进行排序,就解决了这道题目
from datetime import date
n = input()
year = int(n[:2])
month = int(n[3:5])
day = int(n[6:])
d = set()
def y(year):
year1 = 0
if year >= 60:
year1 = 1900 + year
else:
year1 = 2000 + year
return year1
def Date(a, b, c):
try:
day = date(y(a), b, c)
d.add(str(day))
except:
i = 1
Date(year, month, day)
Date(day, year, month)
Date(day, month, year)
d = list(d)
d.sort()
for j in d:
print(j)
排序类题目:
错误票据(学会count()的巧思):
题目的要求非常的简单,自己开始的思路却非常的脑瘫
一开始我想的是在建立列表储存数据后直接依次枚举比较他们的值后查看它们的断号和重号id(如果没有存在比前一个大一的且不重号的就是断号id,如果两个数之间相等,就是重号)完了后我就自信查看大佬题解,发现大佬用了count()方法(当时真的很想给自己俩耳光,觉得自己就是个小丑)不说了,上代码吧。
n = int(input())
li = []
for i in range(n):
for j in map(int, input().split()): # 将输入的字符串转换为整数列表
li.append(j)
li.sort()
m = 0
n = 0
for k in range(min(li), max(li)+1):
if li.count(k) == 0:
m = k
if li.count(k) == 2:
n = k
print(m, n)
两个分糖果(一个贪心另一个字典序):
贪心的:
这道题目我当时是在课上用纸笔画了一下,发现糖果的交换过程实质就是依次后移的过程,但我们需要单独注意到末尾传递糖果时是要归为到首位的(要点其一),然后就是我们的所给出的糖果数目的计算方法,一开始我决定直接单纯枚举即可,后来发现不仅慢,而且自己还写错了(orz),查看了大佬的题解后发现了更好的方法:即,开始的糖果总数和每轮传递的糖果数单独列出进行存储后随着后续的遍历实时更新(实现了在分配糖果时,记录上一个孩子给下一个孩子的糖果数,并更新下一个孩子的糖果数。)最后直接统计结束的糖果总数与开始的糖果总数相减即是补发的数量
代码如下:
n = int(input())
start = list(map(int,input().split()))
ans = sum(start)
i = 0
a= start[0] // 2
# 列表遍历
# 分支判断: 奇数给糖,数目相等时终止循环
# cnt 计数
# while 起手
# 列表首尾特殊情况单独列出
while len(start) != start.count(start[0]):
for i in range(n):
if i +1 == n:
i = -1
start[i+1], a = start[i+1] + a - start[i+1] // 2, start[i+1]//2
if start[i+1] % 2 != 0:
start[i+1] += 1
cnt = sum(start) -ans
print(cnt)
另一个分糖果题目这里直接附代码了(懒狗莫得办法):
# 一开始思路错误的,重点应该在于使字典序最大,随后才是开心程度尽量小
n,x= map(int, input().split())
s = input()
s = sorted(s) # 重点在于已经排序,排序后字典序大的已经提前
# 第一种情况: 第一波分派后已经出现了不同的字母
if s[x-1] != s[0]:
print(s[x-1])
# 第二种情况: 分派后首字母都一致,直接输出最后一个
else:
if s[x] == s[-1]:
print(s[x-1],end='')
# 第三种:
for i in range(x,n,x):
print(s[i], end='')
else:
for i in s[x-1:]:
print(i,end='')
# 请在此输入您的代码
ps:这题一开始还读错题了导致卡了很久不过比起后面一道题,这题读题所犯的错误还是小的。
三国游戏(注意读题啊啊啊啊啊啊!!!!!!!):
这题重点在于读题:
第一,题目没让求中间谁赢了对应的最大事件数,而是最终胜利的最大事件数
第二,给的所有事件它不一定都发生(可以有不发生的(这里直接卡了我半个钟头,当时我挠破脑袋都想不明白,用例给的应该是-1怎么就变成2了))
只要读明白了这两点,你就做完这题的一半了
上代码:
n = int(input())
Xli = list(map(int, input().split()))
Yli = list(map(int, input().split()))
Zli = list(map(int, input().split()))
newX = sorted([Xli[i] - Yli[i] - Zli[i] for i in range(n)], reverse = True)
newY = sorted([Yli[i] - Xli[i] - Zli[i] for i in range(n)], reverse = True)
newZ = sorted([Zli[i] - Xli[i]- Yli[i] for i in range(n)] , reverse = True)
x = y = z = 0
cnt = -1
for i in range(n):
x += newX[i]
y += newY[i]
z += newZ[i]
if x > 0 or y > 0 or z > 0:
cnt = max(cnt, i+1)
print(cnt if cnt != -1 else -1)# 这里不能将-1判断写进前面的循环体里,不然就重复了。
本周总结:
本周一开始在DFS和DP上遇到了挫折,然而留给我的时间已经不多了,时间宛如风中残烛,在接下来的一周里我决定优先把重点放在DFS上从递归递推开始重新再过一遍,这一周自己也是感觉最累的一周。希望自己能克服困难,啃下这块硬骨头,愿看到这里的诸君共勉,最后能攻克难关,取得好成绩,你我共勉,祝各位武运昌隆!!!!!
(图片转自黑大葛格视频中的ai制图)