蓝桥杯---纯职业小组(c语言)

news2025/1/11 22:58:22

问题描述

在蓝桥王国,国王统治着一支由n 个小队组成的强大军队。每个小队都由相同职业的士兵组成。具体地,第i 个小队包含了 bi名职业为ai的士兵。近日,国王计划在王宫广场举行一场盛大的士兵检阅仪式,以庆祝王国的繁荣昌盛。然而,在士兵们入场的过程中,一场突如其来的风暴打乱了他们的行列,使得不同小队的士兵混杂在一起,次序乱成一团,尽管国王无法知道每个士兵的具体职业,但为了确保仪式能顺利进行,国王打算从这些混乱的士兵中选出一部分,组成k 个“纯职业小组”进行检阅。一个“纯职业小组”定义为由3 名同职业的士兵组成的队伍。请问,国王至少需要选择多少名士兵,才能确保这些士兵可以组成 k 个“纯职业小组”。

输入格式

输入包含多组数据。 第一行包含一个整数 T,表示有T 组数据。对于每组数据:第一行包含两个nt和k,表示小队的数量和要组成的纯职业小组的数量。接下来的 nt行,每行包含两个整数 ai和bi,表示第i 个小队中士兵的职业和数量。

输出格式

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

样例输入

2

3 2

1 3

2 3

3 3

3 5

1 3

2 3

3 3

样例输出

8

-1

样例说明

在第一个样例中,要想组成2 个“纯职业小组”,国王至少需要选择 8 名士兵。若只选择了 7 名士兵,则这7 名士兵的职业可能为1,1,1,2,2,3,3,无法组成2 个“纯职业小组”。

在第二个样例中,即使选择了所有士兵,也无法组成 5 个“纯职业小组”,因此输出 −1

思路讲解:

程序需要处理多组数据,每组数据包含小队数量 n 和要组成的纯职业小组数量 k,以及每个小队的职业和士兵数量信息。对于每组数据,程序会计算出最少需要选取多少士兵才能满足组成 k 个 “纯职业小组” 的要求,如果无法满足则输出 -1。

具体设计思路

  1. 哈希表的实现

    • 由于 C 语言没有内置的 unordered_map 这样方便的哈希表容器,因此使用自定义的哈希表结构来存储数据。
    • Node 结构体:包含 key(职业)、value(士兵数量)和 next 指针,用于解决哈希冲突,通过链表法将具有相同哈希索引的元素链接在一起。
    • createNode 函数:创建一个新的 Node 节点,为节点分配内存并进行初始化,若内存分配失败会输出错误信息并终止程序。
    • insert 函数:根据键(职业)的哈希值找到在哈希表中的位置,如果该位置为空,将新节点插入此处;若不为空,则将新节点添加到链表的末尾。
    • find 函数:根据键的哈希值找到在哈希表中的位置,然后遍历链表查找节点,若找到则返回该节点,否则返回 NULL
    • freeHashTable 函数:释放哈希表占用的内存,防止内存泄漏,遍历哈希表的每个位置,释放每个位置上的链表节点。
  2. 主函数部分

    • 首先,程序读取测试数据的组数 T
    • 对于每组数据:
      • 读取 n(小队数量)和 k(纯职业小组数量),并将 k 减 1,这可能是为了后续计算的便利性。
      • 创建哈希表 arr 存储每个小队的信息,使用 calloc 函数分配内存,将内存初始化为 0。
      • 读取每个小队的信息,使用 find 函数查找是否已经存在该职业的节点,如果不存在则使用 insert 函数插入新节点,如果已存在则更新该节点的士兵数量。
      • 初始化 ret 为 0,用于存储最终结果(已选士兵数量),hash 数组用于存储处理后的余数信息(如士兵数量除以 3 的余数)。
      • 遍历哈希表,处理每个小队的士兵数量:
        • 对于士兵数量 b 小于 3 的小队,将其士兵数量累加到 ret 中。
        • 对于士兵数量 b 大于等于 3 的小队,先将 ret 加 2,然后将 b 减 2。接着计算 b 除以 3 的商和余数,将商累加到 hash[3] 中,余数对应的 hash 位置加 1。
      • 处理 k - 1 个队伍的情况:
        • 从 i = 3 开始,逐步减小 i,检查 hash[i] 与 k 的大小关系。
        • 如果 hash[i] 小于 k,将 i * hash[i] 累加到 ret 中,将 hash[i] 置为 0,并从 k 中减去 hash[i]
        • 如果 hash[i] 大于等于 k,将 i * k 累加到 ret 中,将 k 置为 0,并从 hash[i] 中减去 k,同时跳出循环。
      • 最后根据 k 的值和 hash 数组判断结果:
        • 如果 k 为 0 且 hash[3] + hash[2] + hash[1] 大于 0,说明可以完成任务,输出 ret + 1
        • 否则,输出 -1。
      • 释放哈希表的内存,防止内存泄漏。

关键细节

  • 哈希表的使用是为了方便存储和管理不同职业的士兵数量,避免使用复杂的数组存储方式。
  • 对 k - 1 个队伍的处理是为了逐步尝试能否满足组成 k 个纯职业小组的条件,根据不同余数情况分配士兵数量。
  • 在计算士兵数量和余数时,将士兵数量先减去 2 再处理余数,是为了后续更方便地计算所需的最少士兵数。
#include <stdio.h>
#include <stdlib.h>

// 定义一个结构体作为哈希表的节点
typedef struct Node {
    int key;
    int value;
    struct Node* next;
} Node;

// 创建一个新的节点
Node* createNode(int key, int value) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    if (newNode == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(1);
    }
    newNode->key = key;
    newNode->value = value;
    newNode->next = NULL;
    return newNode;
}

// 向哈希表中插入元素
void insert(Node** hashTable, int size, int key, int value) {
    int index = abs(key) % size;
    Node* newNode = createNode(key, value);
    if (hashTable[index] == NULL) {
        hashTable[index] = newNode;
    } else {
        Node* temp = hashTable[index];
        while (temp->next!= NULL) {
            temp = temp->next;
        }
        temp->next = newNode;
    }
}

// 在哈希表中查找元素
Node* find(Node** hashTable, int size, int key) {
    int index = abs(key) % size;
    Node* temp = hashTable[index];
    while (temp!= NULL) {
        if (temp->key == key) {
            return temp;
        }
        temp = temp->next;
    }
    return NULL;
}

// 释放哈希表内存
void freeHashTable(Node** hashTable, int size) {
    for (int i = 0; i < size; ++i) {
        Node* temp = hashTable[i];
        while (temp!= NULL) {
            Node* toFree = temp;
            temp = temp->next;
            free(toFree);
        }
    }
    free(hashTable);
}

#define HASH_SIZE 1000  // 哈希表的大小,可根据需要调整

int main() {
    long long T, n, k;
    scanf("%lld", &T);
    while (T--) {
        scanf("%lld %lld", &n, &k);
        --k;

        Node** arr = (Node**)calloc(HASH_SIZE, sizeof(Node*));
        if (arr == NULL) {
            fprintf(stderr, "Memory allocation failed\n");
            exit(1);
        }
        int a, b;
        for (int i = 0; i < n; ++i) {
            scanf("%d %d", &a, &b);
            Node* node = find(arr, HASH_SIZE, a);
            if (node == NULL) {
                insert(arr, HASH_SIZE, a, b);
            } else {
                node->value += b;
            }
        }

        long long ret = 0;
        long long hash[4] = {0};
        for (int i = 0; i < HASH_SIZE; ++i) {
            Node* temp = arr[i];
            while (temp!= NULL) {
                int b = temp->value;
                if (b < 3) {
                    ret += b;
                } else {
                    ret += 2;
                    b -= 2;

                    hash[3] += b / 3;
                    ++hash[b % 3];
                }
                temp = temp->next;
            }
        }

        // k - 1 个队伍最多多少个人
        for (int i = 3; i > 0; --i) {
            if (hash[i] < k) {
                ret += i * hash[i];
                hash[i] = 0;
                k -= hash[i];
            } else {
                ret += i * k;
                k = 0;
                hash[i] -= k;
                break;
            }
        }

        if (k == 0 && hash[3] + hash[2] + hash[1] > 0) {
            printf("%lld\n", ret + 1);
        } else {
            printf("-1\n");
        }

        freeHashTable(arr, HASH_SIZE);
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2275162.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vscode开启调试模式,结合Delve调试器调试golang项目详细步骤

1.前期准备 (1).在vs code中的扩展程序中搜索并安装Go扩展程序 (2).安装 Delve 调试器 go install github.com/go-delve/delve/cmd/dlvlatest (3).打开vs code的命令面板&#xff0c;输入Go: Install/Update Tools&#xff0c;并单击该命令执行&#xff0c;安装或更新Go语…

Postman接口测试03|执行接口测试、全局变量和环境变量、接口关联、动态参数、断言

目录 七、Postman 1、安装 2、postman的界面介绍 八、Postman执行接口测试 1、请求页签 3、响应页签 九、Postman的环境变量和全局变量 1、创建环境变量和全局变量可以解决的问题 2、postman中的操作-全局变量 1️⃣手动设置 2️⃣代码设置 3️⃣界面获取 4️⃣代…

Python Matplotlib教程-Matplotlib 多子图布局

Python Matplotlib 多子图布局 Matplotlib 是 Python 中最常用的数据可视化库&#xff0c;它提供了强大的功能来绘制不同类型的图表。在实际应用中&#xff0c;通常需要将多个图表绘制在同一个画布上&#xff0c;这就需要用到 多子图布局。本篇文章将详细介绍如何使用 Matplot…

【Java项目】基于SpringBoot的【校园新闻系统】

【Java项目】基于SpringBoot的【校园新闻系统】 技术简介&#xff1a;本系统使用采用B/S架构、Spring Boot框架、MYSQL数据库进行开发设计。 系统简介&#xff1a;主要包括二大功能模块&#xff0c;即用户功能模块和管理员功能模块。系统中的核心用户是管理员&#xff0c;管理员…

c++入门之 命名空间与输入输出

1、命名空间 1.1使用命名空间的原因 先看一个例子&#xff1a; #include <iostream>int round 0;int main() {printf("%d", round);return 0; }请问&#xff0c;这个程序能跑起来吗&#xff1f; 答案是否定的 原因是&#xff0c;当我们想创建一个全局变量 …

【网络安全渗透测试零基础入门】之XSS攻击获取用户cookie和用户密码(实战演示)

前言 大家好&#xff0c;我是demon 这是demon给粉丝盆友们整理的网络安全渗透测试入门阶段XSS攻击教程。 本阶段主要讲解XSS攻击获取用户cookie和用户密码。 喜欢的朋友们&#xff0c;记得给晓晓点赞支持和收藏一下&#xff0c;关注我&#xff0c;学习黑客技术。 简介 该…

HarmonyOS开发:ArkTS初识

ArkTS基本语法 ArkTS语言简介 ArkTS是鸿蒙生态的应用开发语言。基本语法风格与TypeScript&#xff08;简称TS&#xff09;相似&#xff0c;在TS的生态基础上进一步扩展&#xff0c;继承了TS的所有特性&#xff0c;是TS的超集。 基本语法概述 扩展能力 基础语法&#xff1a…

【YOLOv8杂草作物目标检测】

YOLOv8杂草目标检测 算法介绍模型和数据集下载 算法介绍 YOLOv8在禾本科杂草目标检测方面有显著的应用和效果。以下是一些关键信息的总结&#xff1a; 农作物幼苗与杂草检测系统&#xff1a;基于YOLOv8深度学习框架&#xff0c;通过2822张图片训练了一个目标检测模型&#xff…

【python A* pygame 格式化 自定义起点、终点、障碍】

- pip install pygame test.py(chatgpt版本) 空格键&#xff1a;运行 A* 算法。CtrlC 键&#xff1a;清空路径。CtrlS 键&#xff1a;保存当前地图到 map.json 文件。CtrlL 键&#xff1a;从 map.json 文件加载地图。 import pygame import json from queue import PriorityQ…

xfs扩容目录lvm

pve增加磁盘&#xff1a; -bash-4.2# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 50G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 49G 0 part ├─centos-root 253:0 …

Pathview包:整合表达谱数据可视化KEGG通路

Pathview是一个用于整合表达谱数据并用于可视化KEGG通路的一个R包&#xff0c;其会先下载KEGG官网上的通路图&#xff0c;然后整合输入数据对通路图进行再次渲染&#xff0c;从而对KEGG通路图进行一定程度上的个性化处理&#xff0c;并且丰富其信息展示。&#xff08;KEGG在线数…

汽车免拆诊断 | 2007款保时捷Carrera S车行驶中发动机冷却液温度报警灯异常点亮

故障现象 一辆2007款保时捷Carrera S车&#xff0c;搭载3.8 L自然吸气发动机&#xff0c;累计行驶里程约为7.8万km。车主反映&#xff0c;车辆行驶一段距离后&#xff0c;组合仪表上的发动机冷却液温度报警灯异常点亮。为此&#xff0c;在其他维修厂已更换过节温器、发动机冷却…

【PPT解密】ppt只读文档怎么改成可编辑文档

PPT文档打开是只读模式&#xff0c;如何改成可编辑文档呢&#xff1f;这需要分几种情况来说&#xff0c;所以今天将介绍几种方法帮助PPT只读文档改为可编辑文档。 方法一&#xff1a; 我们可以先查看一下文件属性&#xff0c;属性中有只读属性&#xff0c;当我们打开文档之后…

[java基础-集合篇]优先队列PriorityQueue结构与源码解析

优先队列PriorityQueue 优先级队列表示为平衡二进制堆&#xff1a; queue[n] 的两个子级是 queue[2*n1] 和 queue[2*&#xff08;n1&#xff09;]。 注&#xff1a;左子节点index2*parentIndex1,右子节点index2*parentIndex2,源码中计算parent位置时就是这样反过来计算的 优…

ROS2+OpenCV综合应用--11. AprilTag标签码跟随

1. 简介 apriltag标签码追踪是在apriltag标签码识别的基础上&#xff0c;增加了小车车体运动的功能&#xff0c;控制车体从而使摄像头会保持标签码在视觉中间左右运动&#xff0c;在根据物体在摄像头成像近大远小的原理根据这一特性&#xff0c;从而实现标签码跟随功能。 2. 启…

matlab编写分段Hermite插值多项式

文章目录 原理使用分段Hermite插值多项式原因公式第一类的两个插值积函数第二类的两个插值积函数 例题法一法二 代码分段 Hermite 插值的思路&#xff1a;分段 Hermite 插值多项式的构造&#xff1a;MATLAB 实现代码&#xff1a;结果如图&#xff1a;注归一化变量的作用&#x…

小米路由器IPv6 功能使用指南

本文不限于多层路由使用IPv6 的情况&#xff0c;提供解决IPv6 无法获取的更硬核的方法&#xff0c;需要有ssh 工具。&#xff08;无安卓设备&#xff0c;测试环境win、mac、ios&#xff09; 首先明确一点&#xff0c;就是如果想让你的设备得到GUA 地址&#xff0c;即访问 6.i…

#渗透测试#网络安全# 一文了解什么是跨域CROS!!!

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

国产编辑器EverEdit - 扩展脚本:关闭所有未修改文档

1 扩展脚本&#xff1a;关闭所有未修改文档 1.1 应用场景 当用户打开过多文档时&#xff0c;部分文档已经修改&#xff0c;而大部分没有修改&#xff0c;为了减少在众多已打开文档中来回跳转的不便&#xff0c;可以将没有修改的文档全部关闭&#xff0c;但目前提供的快速关闭窗…

IIS部署.NetCore/.Net8/.Net9项目(从装环境到配置Swagger)

一、介绍 随着.NetCore开源、以及版本的更新迭代&#xff0c;.NetCore的性能越来越好、功能也越来越丰富&#xff0c;作为纯后端提供Api已经变得越来越频繁&#xff0c;与之配套的接口组件Swagger也成为很多人的选择。下面介绍在IIS上部署Swagger的详细过程。 二、安装IIS服务…