赞
踩
优先队列是队列数据结构实现,其中根据优先级处理对象,在优先队列中,添加的对象根据其优先级,默认情况下,优先级由对象的自然顺序决定的。队列构建时提供的比较器可以覆盖默认优先级。
优先队列就是一个堆,它可以维护一个集合的最大值(或最小值),可以在很优秀的时间复杂度(log级别)内进行查询,插入push和删除pop.
问题描述
小雷拿到了一个数组,他计算了一下数组的和,感觉和也太大了,所以他准备对数组中的每个元素进行取余操作,让数组的和变得小一点。
具体来说,给定一个数组 a ,共有 q 次操作,每次操作给定一个值 x ,对数组的每个元素对 x 进行一次取模,输出每次操作后,数组所有元素的和。
输入格式
第一行有两个整数n,q ,代表数组 a 的元素个数和操作个数。
第二行输入 n 个元素,代表数组 a 。
第三行输入 q 个元素,代表 q 次操作。
输出格式
输出仅一行,包含 q 个由空格分开的整数,第 i 个整数代表第 qi 次操作后的结果。
样例输入
- 5 3
- 1 2 3 4 5
- 4 2 1
样例输出
7 3 0
说明
初始数组为 [1,2,3,4,5]
,和为 15 。
进行第一次 x 为 4 的取模操作后,数组变为 [1,2,3,0,1]
,和为 7 。
进行第二次 x 为 2 的取模操作后,数组变为 [1,0,1,0,1]
,和为 3 。
进行第三次 x 为 1 的取模操作后,数组变为 [0,0,0,0,0]
,和为 0。
构建数值从大到小的优先序列
每次比较对头和x的大小关系,如果队头大于x,把对头弹出来,将队头对x取模的值压入队列中。
代码
- package dui;
- import java.util.*;
- public class chapter1 {
-
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- Scanner scan=new Scanner(System.in);
- int n=scan.nextInt();
- int q=scan.nextInt();
- long sum=0;
- PriorityQueue<Integer> queue=new PriorityQueue<>((o1,o2)->o2-o1);
- for(int i=0;i<n;i++) {
- int x=scan.nextInt();
- queue.add(x);
- sum+=x;
- }
- while(q-->0) {
- //q次操作
- int k=scan.nextInt();
- while(!queue.isEmpty()&&queue.peek()>=k) {
- //判断队列是否为空,以及对头中的元素大于我们当前要取余的值
- int x=queue.poll();//弹出(一直弹出比k大的数)
- sum-=x;
- queue.add(x%k);//对k取余后的值添加到队列中
- sum+=x%k;
- }
- System.out.print(sum+" ");//每次需要输出sum
- }
-
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。