招募队员 蓝桥周赛

3.招募队员【算法赛】 - 蓝桥云课 (lanqiao.cn)

问题描述

为了对抗蠢蠢欲动的异能兽,炎龙侠、飞鹰侠、黑犀侠、雪獒侠和地虎侠五位铠甲勇士决定各自组建战队,迎战强敌。

消息一出,光影村的铠甲后人热血沸腾,纷纷组队报名。

现共有 𝑛n 支队伍,每支队伍由五名年轻小伙组成,他们各自填写了最想跟随的铠甲勇士编号(11 代表炎龙侠,22 代表飞鹰侠,以此类推,55 代表地虎侠)。用 𝑎𝑖,𝑗ai,j​ 表示第 𝑖i 支队伍的第 𝑗j 名队员最想跟随的铠甲勇士的编号。例如,𝑎3,2=4a3,2​=4 就表示第 33 支队伍的第 22 名队员想加入雪獒侠的战队。

为了公平公正,每位铠甲勇士需从报名队伍中选择一个连续的区间 [𝑙,𝑟][l,r](1≤𝑙≤𝑟≤𝑛1≤l≤r≤n)进行招募。但有一个重要的规则:对于区间内的每一支队伍,该铠甲勇士必须且只能招募一名心仪他的队员。如果某支队伍中没有队员想跟随这位铠甲勇士,那么这位铠甲勇士就不能选择包含这支队伍的区间。

现在,五位铠甲勇士都想知道自己最多能招募到多少队员,以便制定最佳的作战策略。你能帮助他们计算出各自可招募的最大人数吗?

输入格式

第一行包含一个整数 𝑛n(1≤𝑛≤1051≤n≤105),表示报名队伍的总数。

接下来 𝑛n 行,每行包含五个整数 𝑎𝑖,1,𝑎𝑖,2,𝑎𝑖,3,𝑎𝑖,4,𝑎𝑖,5ai,1​,ai,2​,ai,3​,ai,4​,ai,5​(1≤𝑎𝑖,𝑗≤51≤ai,j​≤5),表示第 𝑖i 支队伍中五名队员想跟随的铠甲勇士编号。

输出格式

输出一行,包含五个整数,分别表示炎龙侠、飞鹰侠、黑犀侠、雪獒侠和地虎侠最多能招募到的队员数量。

样例输入

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

样例输出

5 2 2 2 2

运行限制

语言最大运行时间最大运行内存
C++1s256M
C1s256M
Java2s256M
Python33s256M
PyPy33s256M
Go3s256M
JavaScript3s256M
import java.util.ArrayList;
import java.util.Scanner;

// 主类,按照题目要求类名必须为Main
public class Main {
    public static void main(String[] args) {
        // 创建Scanner对象用于从控制台读取用户输入
        Scanner scan = new Scanner(System.in);

        // 读取报名队伍的总数n
        int n = scan.nextInt();

        // 创建一个二维的ArrayList,用于存储每支队伍队员想跟随的铠甲勇士编号信息
        // 外层ArrayList对应每支队伍,内层ArrayList对应每支队伍里的五名队员的选择
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();

        // 循环读取每支队伍的信息
        for (int i = 0; i < n; i++) {
            // 为每支队伍创建一个新的内层ArrayList,用于存储该队伍五名队员的选择
            list.add(new ArrayList<>());
            // 循环读取该队伍里五名队员想跟随的铠甲勇士编号,并添加到内层ArrayList中
            for (int j = 0; j < 5; j++) {
                list.get(i).add(scan.nextInt());
            }
        }

        // 依次计算每位铠甲勇士(编号从1到5)最多能招募到的队员数量
        for (int i = 1; i <= 5; i++) {
            int max = 0;  // 用于记录当前铠甲勇士能招募到的最大连续队员数量
            int c = 0;    // 用于临时记录当前连续区间内想跟随当前铠甲勇士的队员数量

            // 遍历每支队伍,检查队伍中是否有队员想跟随当前铠甲勇士(编号为i)
            for (int j = 0; j < list.size(); j++) {
                // 如果当前队伍中有队员想跟随当前铠甲勇士(编号为i)
                if (list.get(j).contains(i)) {
                    c++;
                } else {
                    // 如果当前队伍中没有队员想跟随当前铠甲勇士,更新最大连续队员数量max
                    // 并重置临时计数c为0,准备统计下一个可能的连续区间
                    max = Math.max(max, c);
                    c = 0;
                }
            }

            // 处理最后一个连续区间的情况,更新最大连续队员数量max
            max = Math.max(max, c);

            // 输出当前铠甲勇士(编号为i)最多能招募到的队员数量
            System.out.print(max + " ");
        }

        // 关闭Scanner,释放资源
        scan.close();
    }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

// 主类,按照题目要求类名通常为Main(这里假设是满足相关编程作业或测试要求的类名)
public class Main {

    // 创建一个静态的BufferedReader对象,用于从标准输入流(通常是控制台)读取字符数据
    // 它通过将System.in包装在InputStreamReader中实现高效的字符读取
    static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    // 创建一个静态的PrintWriter对象,用于向标准输出流(通常是控制台)写入格式化后的文本数据
    static final PrintWriter pw = new PrintWriter(System.out);

    // 主方法,程序的入口点,当程序启动时会首先执行这个方法
    public static void main(String[] args) throws IOException {

        // 从标准输入读取一个整数n,表示后续输入数据的组数或相关循环次数等(具体含义需结合题目上下文)
        int n = Integer.parseInt(br.readLine());

        // 创建一个长度为6的整数数组cnt,用于记录某种计数情况(结合后续代码可能是与1到5这几个数字相关的计数)
        // 数组索引0位置未使用,索引1到5分别对应相关情况的计数
        int[] cnt = new int[6];

        // 创建一个长度为6的整数数组ans,用于存储最终的结果(同样索引0位置未使用,索引1到5对应相关结果)
        int[] ans = new int[6];

        // 开始一个循环,循环次数由之前读取的n决定
        for (int i = 0; i < n; i++) {

            // 使用Java 8的流(Stream)特性将从控制台读取的一行字符串数据(以空格分隔的数字字符串)
            // 先进行分割操作得到字符串数组,然后将每个字符串转换为整数,并收集到一个Set集合中
            // 这样可以去除重复的数字,并且便于后续判断某个数字是否在集合中
            Set<Integer> set = Arrays.stream(br.readLine().split(" "))
                   .map(Integer::parseInt).collect(Collectors.toSet());

            // 遍历数字1到5
            for (int j = 1; j <= 5; j++) {

                // 如果当前集合set中包含数字j,说明出现了一次与j相关的情况,对cnt数组中对应的索引位置计数加1
                if (set.contains(j)) cnt[j]++;

                // 如果当前集合set中不包含数字j,说明出现了一次间断情况
                // 此时需要比较当前间断情况下之前连续出现的与j相关的最大次数(存储在ans[j]中)和当前连续计数cnt[j]
                // 取两者中的较大值更新ans[j],然后将cnt[j]重置为0,准备统计下一次可能的连续情况
                else {
                    ans[j] = Math.max(ans[j], cnt[j]);
                    cnt[j] = 0;
                }
            }
        }

        // 循环结束后,再次遍历数字1到5
        for (int i = 1; i <= 5; i++) {

            // 处理最后一次循环结束后可能还未更新的情况,再次比较ans[i]和cnt[i]的大小
            // 取两者中的较大值更新ans[i],确保ans[i]存储的是最终的最大相关次数
            ans[i] = Math.max(ans[i], cnt[i]);

            // 将最终的结果(每个数字对应的最大相关次数)输出到标准输出流,每个结果之间用空格隔开
            pw.print(ans[i] + " ");
        }

        // 关闭PrintWriter,确保所有缓冲的数据都被正确写入到标准输出流中,释放相关资源
        pw.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值