每日一题(JAVA)

纯职业士兵

问题描述

在蓝桥王国,国王统治着一支由 nn 个小队组成的强大军队。每个小队都由相同职业的士兵组成。具体地,第 ii 个小队包含了 bibi​ 名职业为 aiai​ 的士兵。

近日,国王计划在王宫广场举行一场盛大的士兵检阅仪式,以庆祝王国的繁荣昌盛。然而,在士兵们入场的过程中,一场突如其来的风暴打乱了他们的行列,使得不同小队的士兵混杂在一起,次序乱成一团,

尽管国王无法知道每个士兵的具体职业,但为了确保仪式能顺利进行,国王打算从这些混乱的士兵中选出一部分,组成 kk 个“纯职业小组”进行检阅。一个“纯职业小组”定义为由 33 名同职业的士兵组成的队伍。

请问,国王至少需要选择多少名士兵,才能确保这些士兵可以组成 kk 个“纯职业小组”。

输入格式

输入包含多组数据。

第一行包含一个整数 TT,表示有 TT 组数据。

对于每组数据:

  • 第一行包含两个整数 ntnt​ 和 kk,表示小队的数量和要组成的纯职业小组的数量。
  • 接下来的 ntnt​ 行,每行包含两个整数 aiai​ 和 bibi​,表示第 ii 个小队中士兵的职业和数量。

输出格式

对于每组数据,输出一个整数,表示为了组成 kk 个“纯职业小组”,国王至少需要选择的士兵数量。如果无论如何也无法组成 kk 个“纯职业小组”,则输出 −1−1。

思路1:

     首先考虑什么情况下输出-1;有两种思考:一个是最初每个队士兵个数小于3的组数数量少于k个。还有一种是军队所有士兵的数量总和小于3*k(就像给的样例2)。

    难点在于想找到至少多少名士兵?先给出多组样例,试试找规律。样例1有三组队伍,每个队伍三人,所以可以化简为aaa,bbb,ccc三组,极端抽取情况就是abcabcab,所以至少需要8人。

      根据极端情况,对样例修改,若三个队伍人员数量分别为二,四,三。可以化简为aa,bbbb,ccc,则极端情况是abcabcbc,也是选8人。

以此类推,试着写出代码。


题解思路

        问至少要挑选多少名士兵,且k组里面每个组都是3人,则需要考虑若有一个组是9人,则可以分为三组,因此先统计出所有组数(在原有基础上分割)。

具体代码

1)Map <Integer, Long> h;  Long表示包装类而不是基本数据类型

2)h = new HashMap<>() ;

3)h.put(a, h.getOrDefault(a , 0L) + b) ;   getOrDefault表示如果存在键a,返回其对应的数值并+b, 若不存在就是0+b,也就是b

4)List<Long> b = new ArrayList<> (h.values()); 将h里面的值提取出来放在集合b中。

思路

继续:

不考虑选取士兵的顺序,极端情况就是每一种类型都选了两个人或者更少(取决于此类型士兵的数量),一直凑不齐第三个,用used记录选过的人数,再将b里面的数量减去

代码

long used = Math.min(b.get(i), 2); 因为可能b里面的人数不足两个人

b.set(i, b.get(i)-used);

import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改
 
public class Main 
    public static void main(String args[]) 
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        int t = scan.nextInt();
 
        for(int j = 0; j < t; j ++ ){
          int n;
          long k;
          n = scan.nextInt();
          k = scan.nextLong();
 
          Map<Integer, Long> h = new HashMap<> ();
 
          for(int i = 0;i < n; i ++ ){
            int a = scan.nextInt();
            long b = scan.nextLong();
           
            h.put(a, h.getOrDefault(a, 0L) + b);
 
          }
 
          List<Long> b = new ArrayList<> (h.values());
 
          long cnt = 0, res = 0;
 
          for(int i = 0; i < b.size(); i ++ ){
 
            long full = b.get(i)/3;
 
            cnt += full;
 
            long used = Math.min(b.get(i), 2);
 
            b.set(i, b.get(i)-used);
 
            res += used; 
          }
 
     }

思路

需要考虑输出为-1

当所有人数除以三的个数都小于k组,表明无法集齐

如果有输出,统计b集合里每个数可以分成几组,计算出余数

if(cnt < k) {
            System.out.println(-1);
          }
          else {
            long c1 = 0, c2 = 0, c3 = 0;
 
            for(long x : b) {
 
              c3 += x/3;
              x %= 3;
              if(x == 1) c1++;
              else if(x == 2) c2 ++;
            }

思路

!!!这里我不明白为什么先k--; res++;

最后一部分代码还是有点乱,需要再想清楚

            k--;
            res++;
 
            long v = Math.min(k, c3);
            k-=v;
            c3-=v;
            res += v*3;
 
            v = Math.min(k, c2);
            k-=v;
            c2-= v;
            res += v*2;
 
            v = Math.min(k, c1);
            k-=v;
            c1-=v;
            res+=v;
            
            System.out.println(res);
          }
 
        }
        scan.close();
    }
}

SQL Prompt是Red Gate Software公司开发的一款强大的SQL代码编辑和优化工具,主要面向数据库开发者和管理员。版本11.0.1.16766是一个更新版本,它提供了更高效、更便捷的SQL编写环境,旨在提升SQL代码的可读性、效率和一致性。这个安装包包含了所有必要的组件,用于在用户的计算机上安装SQL Prompt工具。 SQL Prompt的核心功能包括自动完成、智能提示、格式化和重构。自动完成功能能够帮助用户快速输入SQL语句,减少键入错误;智能提示则基于上下文提供可能的选项,加快编写速度;格式化功能允许用户按照自定义或预设的编码规范对SQL代码进行美化,提升代码的可读性;而重构工具则可以帮助用户优化代码结构,消除潜在问题。 在描述中提到的“代码格式化规则来源于网络”,指的是用户可以通过下载网络上的json文件来扩展或定制SQL Prompt的代码格式化规则。这些json文件包含了特定的格式设置,如缩进风格、空格使用、注释位置等。将这些文件复制到指定的目录(例如:C:\Users\用户名\AppData\Local\Red Gate\SQL Prompt 10\Styles)后,SQL Prompt会读取这些规则并应用到代码格式化过程中,使得用户可以根据个人偏好或团队规范调整代码样式。 以下几点请注意: 1. 经实测,此版本支持最新的Sql Server 2022版的SSMS21 2. 此安装包中不包括keygen,请自行解决
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值