分班问题 、幼儿园分班(C语言)

news/2024/7/20 19:32:37 标签: 算法, c语言, 数据结构, 华为od

题目

幼儿园两个班的小朋友排队时混在了一起,每个小朋友都知道自己跟前面一个小朋友是不是同班,请你帮忙把同班的小朋友找出来
小朋友的编号为整数,与前面一个小朋友同班用Y表示,不同班用N表示

输入

输入为空格分开的小朋友编号和是否同班标志
比如 6/N 2/Y 3/N 4/Y
表示一共有4位小朋友
26是同班,32不同班,43同班
小朋友总数不超过999
0 < 每个小朋友编号 < 999
不考虑输入格式错误

输出

每一行记录一班小朋友的编号 编号用空格分开
并且

  1. 编号需要按照大小升序排列,分班记录中第一个编号小的排在第一行
  2. 如果只有一个班的小朋友 第二行为空
  3. 如果输入不符合要求输出字符串ERROR

示例一

输入

1/N 2/Y 3/N 4/Y
1

输出

1 2
3 4
12

说明

2的同班标记为Y因此和1同班
3的同班标记位N因此和1,2不同班
4的同班标记位Y因此和3同班

示例二

输入

1/N 2/Y 3/N 4/Y 5/Y

输出

1 2
3 4 5

思路

解题思路:

  1. 读取输入:首先通过fgets函数获取用户输入的一行字符串,然后使用strtok函数将其按照空格分割成一个个包含编号和是否同班标志的token(例如:“1/N”、"2/Y"等),并将这些token存入临时数组中。

  2. 初始化学生结构体数组:根据临时数组中的信息,利用sscanf函数将每个token解析为小朋友的编号(id)和是否同班(isClass)标志,并存储到Students结构体数组stu中。

  3. 判断首位合法性:检查首位小朋友是否与前一位小朋友同班。由于没有前一位小朋友,若首位标记为“Y”,则输入非法,输出"ERROR"并结束程序。

  4. 分配班级:遍历整个stu数组,对于每个小朋友:

    • 首位小朋友直接划归到班级1;
    • 若当前小朋友与前一位小朋友同班,则将其划归到前一位所在的班级;
    • 若当前小朋友与前一位小朋友不同班,则将其划归到另一个班级。

    在这个过程中,用两个整数数组class1class2分别记录两个班级的小朋友编号。

  5. 排序输出:对两个班级数组进行升序排序,这里使用C标准库提供的qsort函数进行快速排序。最后分别输出两个班级的小朋友编号,每个编号后面跟一个空格,第二个班级结束后输出换行符。

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 1000

// 定义学生结构体,包含小朋友编号(id)、是否同班标志(isClass)以及所在班级(classId)
typedef struct {
    int id;
    char isClass[2];
    int classId; // 表示小朋友属于一班还是二班
} Students;

// 自定义排序函数,用于对整数数组进行升序排序
int cmp(const void *a, const void *b) { return *(int *)a - *(int *)b; }

int main() {
    char input[3000]; // 输入缓冲区,用于存储用户输入的数据

    // 读取一行用户输入,并移除末尾换行符
    fgets(input, 3000, stdin);
    input[strcspn(input, "\n")] = '\0';

    // 使用strtok函数分割输入字符串为一个个token(小朋友编号和是否同班标志)
    char *token = strtok(input, " ");
    char tmp[MAX][10]; // 临时存储每个token
    int count = 0;     // 记录当前读取到的token数量
    while (token != NULL) {
        strcpy(tmp[count++], token); // 将token复制到临时数组中
        token = strtok(NULL, " ");   // 继续获取下一个token
    }

    // 初始化学生结构体数组,并将读取到的信息存入其中
    Students stu[MAX];
    for (int i = 0; i < count; i++) {
        sscanf(tmp[i], "%d/%s", &stu[i].id, stu[i].isClass);
    }

    // 检查首位小朋友是否与前一位小朋友同班(实际上没有前一位),若同班则输入非法,输出ERROR
    if (strcmp(stu[0].isClass, "Y") == 0) {
        printf("ERROR\n");
        return 0;
    }

    // 定义两个数组分别存储两个班级的小朋友编号
    int class1[MAX], class2[MAX];
    int count1 = 0, count2 = 0; // 分别记录两个班级的人数

    // 遍历所有小朋友信息,根据是否同班标志将他们分配到对应的班级数组中
    for (int i = 0; i < count; i++) {
        // 处理首位小朋友
        if (i == 0) {
            class1[count1++] = stu[i].id;
            stu[i].classId = 1; // 设置班级ID为1
            continue;
        }

        // 若当前小朋友与前一位小朋友同班,则将其划分到同一班级
        if (strcmp(stu[i].isClass, "Y") == 0) {
            stu[i].classId = stu[i - 1].classId;
            // 根据班级ID将小朋友编号添加到对应的班级数组中
            if (stu[i].classId == 1) {
                class1[count1++] = stu[i].id;
            } else if (stu[i].classId == 2) {
                class2[count2++] = stu[i].id;
            }
        }

        // 若当前小朋友与前一位小朋友不同班,则将其划分到另一个班级
        if (strcmp(stu[i].isClass, "N") == 0) {
            // 更新当前小朋友的班级ID,使其与前一位小朋友所在的班级不同
            if (stu[i - 1].classId == 1) {
                stu[i].classId = 2;
            } else if (stu[i - 1].classId == 2) {
                stu[i].classId = 1;
            }
            // 根据更新后的班级ID将小朋友编号添加到对应的班级数组中
            if (stu[i].classId == 1) {
                class1[count1++] = stu[i].id;
            } else if (stu[i].classId == 2) {
                class2[count2++] = stu[i].id;
            }
        }
    }

    // 对两个班级数组分别进行升序排序
    qsort(class1, count1, sizeof(int), cmp);
    qsort(class2, count2, sizeof(int), cmp);

    // 输出两个班级的小朋友编号,每个编号后面跟一个空格
    for (int i = 0; i < count1; i++) {
        printf("%d ", class1[i]);
    }
    printf("\n"); // 换行输出第二个班级
    for (int i = 0; i < count2; i++) {
        printf("%d ", class2[i]);
    }

    return 0;
}

文章目录

    • 题目
    • 输入
    • 输出
    • 示例一
      • 输入
      • 输出
      • 说明
    • 示例二
      • 输入
      • 输出
    • 思路
    • 代码


http://www.niftyadmin.cn/n/5388450.html

相关文章

【八、hyperf项目随docker容器自动启动,无需进入容器手动启动项目】

hyperf项目随docker容器自动启动 项目准备运行的容器进入容器查看项目访问效果开始准备工作(这个项目随容器自动启动,不需要刚才进入项目的手动敲命令了)先创建一个文件夹,名字随意,我这里是提示文件夹已存在了进入文件夹,先准备写一个sh的脚本命令,后面会用到的然后就是…

力扣基础刷题---二分查找

704. 二分查找 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 中心思想&#xff1a;找到中间值&#xff0c;跟中间值比…

【Git】:标签功能

标签功能 一.标签操作二.推送远程标签 标签 tag &#xff0c;可以简单的理解为是对某次commit的⼀个标识&#xff0c;相当于起了⼀个别名。例如&#xff0c;在项⽬发布某个版本的时候&#xff0c;针对最后⼀次commit起⼀个v1.0这样的标签来标识⾥程碑的意义。这有什么⽤呢&…

导出本地环境venv包whl文件。

把python环境 venv 对应包的文件导出成whl文件 将 Python 虚拟环境中包导出到文件&#xff0c;可以方便地在其他电脑上安装相同的环境&#xff0c;无需重复下载。 使用 pip freeze 和 pip download 使用 pip freeze 命令列出所有已安装的包和版本号保存到 requirements.txt …

jenkins报错:Pseudo-terminal will not be allocated because stdin is not a terminal

jenkins的流水线部分代码如下 sh ssh root192.168.2.234 << remotessh cd /var/lib/jenkins/workspace/txkc /usr/local/maven/apache-maven-3.8.6/bin/mvn clean package -U ls remotessh执行流水线出现报错&#xff1a;Pseudo-terminal will not be allocated because…

【寸铁的刷题笔记】树、dfs、bfs、回溯、递归(一)

【寸铁的刷题笔记】树、dfs、bfs、回溯、递归(一) 大家好 我是寸铁&#x1f44a; 总结了一篇刷题关于树、dfs、bfs、回溯、递归的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 105. 从前序与中序遍历序列构造二叉树 模拟分析图 代码实现 /*** Definition for a binary tre…

Python+Flask低代码数据融合引擎工具

我用了2年多时间开发了一个低代码数据融合引擎工具 1.整体界面 2.主要功能 1)通过excel文件生成mysql数据表结构及数据保存 说明:功能细节包括(excel文件上传,文件内容预览,建表导入数据),难点在于对excel数据类型判断,并与mysql数据类型对应 2)建立数据表结构并批量导入数据 …

06 flink 的各个角色的交互

前言 这里主要是 涉及到 flink 中各个角色的交互 TaskManager 和 ResourceManager 的交互 JobMaster 和 ResourceManager 的交互 等等流程 TaskManager 和 ResourceManager 的交互 主要是 包含了几个部分, 如下, 几个菜单 TaskManager向 ResourceManager 注册 Resou…