牛客--分组对话

猿辅导课堂上老师提供了一些角色,学生可以从中选择一个自己喜欢的角色扮演,每3个不同的角色就可以组成一个小组,进行分组对话。
当老师点击开始分组对话按钮的时候,服务器会为已经选择自己角色的同学分配对话小组,请问最多能组成多少个对话小组?

输入描述:
第一行为测试用例数量C(C<=100),接下来的C行每行为一个测试用例

每个用例的第一个数字表示可供选择的角色数量T(T<=1000),接下来的T个数字表示每个角色的选择人数Pi(Pi<=500)

输出描述:
一共C行,每行表示一个测试用例中的最大对话小组数量。
示例1
输入
3
3 1 1 1
3 2 2 3
4 0 2 3 99
输出
1
2
2
说明
对于用例1,正好3个不同角色,每个角色1个人选,于是构成且只能构成一个小组。

对于用例2,在构成两个小组之后,第3个角色单了1人无法构成任何小组,所以最大小组数量是2。

对于用例3,学生扎堆选择了最后一个角色,但是第二个角色只有2个人,所以还是只能构成2个对话小组。


自己的做法: 将最大的三堆 提出,然后 减去 这三堆中最小的,(直接降为0)

实际上大错特错: 这样就直接减少了一个分组,导致最后,很容易造成 凑不成 3个不同的角色组成一个小组。

正解: 利用优先队列 每次从人数最多的三个角色出各取一人 组成一组,然后再放回 优先队列中,(保证每一次都是从人数最多的三个角色出各取一人) 这样保证使其最后的角色人数为(1,1,1) 而不是 (3,0,0)这种情况。

import java.util.PriorityQueue;
import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner input;
        int C, T, i, j;
        int[][] P;
 
        input = new Scanner(System.in);
        C = input.nextInt();
        P = new int[C][];
        for(i = 0; i < C; i++){
            T = input.nextInt();
            P[i] = new int[T];
            for(j = 0; j < T; j++){
                P[i][j] = input.nextInt();
            }
        }
        for(i = 0; i < C; i++){
            System.out.println(solve(P[i]));
        }
        input.close();
    }
 
    private static int solve(int[] P){
        int first, second, third, ans = 0;
        
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a,b)-> b-a);
        
        for(int p : P) {
        	if(p > 0)pq.offer(p);
        }
        
        while(pq.size() > 2){
            first = pq.poll();
            second = pq.poll();
            third = pq.poll();
            if(--first > 0){
                pq.offer(first);
            }
            if(--second > 0){
                pq.offer(second);
            }
            if(--third > 0){
                pq.offer(third);
            }
            ans++;
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值