当前位置:   article > 正文

【算法训练营】数字盒子,重编码,成绩排序(python实现)

【算法训练营】数字盒子,重编码,成绩排序(python实现)

数字盒子

问题描述

你有一个盒子,你可以往里面放数,也可以从里面取出数。

初始时,盒子是空的,你会依次做 Q 个操作,操作分为两类:

  1. 插入操作:询问盒子中是否存在数 x,如果不存在则把数 x 丢到盒子里。
  2. 删除操作:询问盒子中是否存在数 x,如果存在则取出 x。

对于每个操作,你需要输出是否成功插入或删除。

输入格式

第一行一个正整数 Q,表示操作个数。

接下来 Q 行依次描述每个操作。每行 2 个用空格隔开的非负整数 op,x 描述一个操作:op 表示操作类型,op=1 则表示这是一个插入操作,op=2 则表示这是一个删除操作;x 的意义与操作类型有关,具体见题目描述。

输出格式

按顺序对所有操作输出,对于每个操作输出一行,如果成功则输出“Succeeded”(不含引号),如果失败则输出“Failed”(不含引号)。

样例输入

  1. 6
  2. 1 100
  3. 1 100
  4. 2 100
  5. 1 200
  6. 2 100
  7. 2 200

样例输出

  1. Succeeded
  2. Failed
  3. Succeeded
  4. Succeeded
  5. Failed
  6. Succeeded

数据范围

对于 60% 的数据,保证 x<10^5。

对于 100% 的数据,保证 x<10^18,Q≤5*10^5。

对于所有数据,保证 op∈{1,2}。

时间限制:1 s

空间限制:256 MB

提示

[对于 x 较小的情况,我们只需要用数组记录每个数是否在盒子里即可。]

[对于 x 较大的情况,我们可不可以用什么方法把它们“变小”呢?可以想想哈希表哦!]

代码实现

  1. class Box:
  2. def __init__(self):
  3. self.contents = set()
  4. def insert(self, x):
  5. if x not in self.contents:
  6. self.contents.add(x)
  7. return "Succeeded"
  8. else:
  9. return "Failed"
  10. def remove(self, x):
  11. if x in self.contents:
  12. self.contents.remove(x)
  13. return "Succeeded"
  14. else:
  15. return "Failed"
  16. def main():
  17. q = int(input())
  18. box = Box()
  19. for _ in range(q):
  20. op, x = map(int, input().split())
  21. if op == 1:
  22. result = box.insert(x)
  23. elif op == 2:
  24. result = box.remove(x)
  25. print(result)
  26. if __name__ == "__main__":
  27. main()

重编码

问题描述

输入格式

输出格式

输出一行一个整数,表示整篇文章重编码后的最短长度。

样例输入

  1. 4
  2. 1
  3. 1
  4. 2
  5. 2

样例输出

12

样例解释

数据范围

提示

[我们希望越长的串出现次数越少,那么贪心地考虑,让出现次数少的串更长。]

[于是我们先区分出出现次数最少的 2 个串,在它们的开头分别添加 0 和 1。]

[接着,由于它们已经被区分(想一想,为什么?),所以我们可以把它们看作是**一个**单词,且其出现次数为它们的和,然后继续上面的“添数”和“合并”操作。]

[这样,我们不停地“合并单词”,直到只剩 1 个单词,即可结束。]

[可以证明这是最优的。]

代码实现

  1. import heapq
  2. # 这是求解整个问题的函数
  3. # 返回值:答案
  4. def get_answer():
  5. n = int(input())
  6. w = [int(input()) for _ in range(n)]
  7. # 将所有w加入优先队列pq中
  8. pq = []
  9. for i in range(n):
  10. heapq.heappush(pq, w[i])
  11. sum_val = 0 # 置零返回值
  12. while len(pq) > 1: # 当pq中仍有超过多少元素时进行循环呢?
  13. new_ele = 0 # 这是本次合并后将要加入队列的新元素
  14. # 从pq中取出最小的两个元素并合并
  15. for k in range(2):
  16. new_ele += heapq.heappop(pq)
  17. sum_val += new_ele # 将本次合并对答案的贡献加入答案
  18. heapq.heappush(pq, new_ele) # 将新元素加入队列
  19. return sum_val # 返回答案
  20. # 获取答案并输出
  21. result = get_answer()
  22. print(result)

成绩排序

问题描述

有 n 名学生,它们的学号分别是 1,2,…,n。这些学生都选修了邓老师的算法训练营、数据结构训练营这两门课程。

学期结束了,所有学生的课程总评都已公布,所有总评分数都是 [0,100] 之间的整数。巧合的是,不存在两位同学,他们这两门课的成绩都完全相同

邓老师希望将这些所有的学生按这两门课程的总分进行降序排序,特别地,如果两位同学的总分相同,那邓老师希望把算法训练营得分更高的同学排在前面。由于上面提到的巧合,所以,这样排名就可以保证没有并列的同学了。

邓老师将这个排序任务交给了他的助教。可是粗心的助教没有理解邓老师的要求,将所有学生按学号进行了排序。

邓老师希望知道,助教的排序结果中,存在多少逆序对

如果对于两个学生 (i,j) 而言,i 被排在了 j 前面,并且i 本应被排在 j 的后面,我们就称 (i,j) 是一个逆序对

请你先帮邓老师把所有学生按正确的顺序进行排名,再告诉他助教的错误排名中逆序对的数目。

输入格式

第一行一个整数 n,表示学生的个数。

第 2 行到第 n+1 行,每行 2 个用空格隔开的非负整数,第 i+1 行的两个数依次表示学号为 i 的同学的算法训练营、数据结构训练营的总评成绩。

输出格式

输出包含 n+1 行。

前 n 行表示正确的排序结果,每行 4 个用空格隔开的整数,第 i 行的数依次表示排名为 i 的同学的学号、总分、算法训练营成绩、数据结构训练营成绩。

第 n+1 行一个整数,表示助教的错误排名中逆序对的数目。

样例输入

  1. 3
  2. 95 85
  3. 90 90
  4. 100 99

样例输出

  1. 3 199 100 99
  2. 1 180 95 85
  3. 2 180 90 90
  4. 2

样例解释

学号为 3 的同学总分为 199,是最高的,所以他应该排第一名。

学号为 1 的同学虽然总分与学号为 2 的同学一致,但是他的算法训练营成绩更高,所以在排名规则下更胜一筹。

原错误排名中的逆序对数目为 2 ,这些逆序对分别为 (1,3) 和 (2,3)。

数据范围

对于 25% 的数据,保证 n=3。

对于 50% 的数据,保证 n≤10。

对于另外 25% 的数据,保证所有同学的总分两两不同。

对于 100% 的数据,保证 n≤5,000 ,且保证不存在成绩完全相同的学生。

时间限制:10 sec

空间限制:256 MB

提示

[可以使用起泡排序将所有学生进行排名。]

[善良的助教提醒你,在起泡排序的过程中,每次交换都会使逆序对数目减少 1 哦!想一想,为什么?]

这道题可以设计出时间复杂度为 O(nlogn) 的算法。]

代码实现

  1. def bubble_sort(arr):
  2. n = len(arr)
  3. inversion_count = 0
  4. for i in range(n):
  5. for j in range(0, n-i-1):
  6. # 如果当前学生的总分更高,或者总分相同但算法训练营成绩更高,进行交换
  7. if arr[j][1] < arr[j+1][1] or (arr[j][1] == arr[j+1][1] and arr[j][2] < arr[j+1][2]):
  8. arr[j], arr[j+1] = arr[j+1], arr[j]
  9. inversion_count += 1
  10. return inversion_count
  11. # 输入
  12. n = int(input())
  13. students = []
  14. for i in range(1, n+1):
  15. scores = list(map(int, input().split()))
  16. students.append((i, scores[0] + scores[1], scores[0], scores[1]))
  17. # 使用气泡排序对倒序进行排序和计数
  18. inversion_count = bubble_sort(students)
  19. # 输出正确排名
  20. for i in range(n):
  21. print(f"{students[i][0]} {students[i][1]} {students[i][2]} {students[i][3]}")
  22. # 输出助教错误排名中的逆序对数目
  23. print(inversion_count)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/79737
推荐阅读
相关标签
  

闽ICP备14008679号