本文主要是介绍分班问题 、幼儿园分班(C语言),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目
幼儿园两个班的小朋友排队时混在了一起,每个小朋友都知道自己跟前面一个小朋友是不是同班,请你帮忙把同班的小朋友找出来
小朋友的编号为整数,与前面一个小朋友同班用Y
表示,不同班用N
表示
输入
输入为空格分开的小朋友编号和是否同班标志
比如 6/N 2/Y 3/N 4/Y
表示一共有4
位小朋友
2
和6
是同班,3
和2
不同班,4
和3
同班
小朋友总数不超过999
0 < 每个小朋友编号 < 999
不考虑输入格式错误
输出
每一行记录一班小朋友的编号 编号用空格分开
并且
- 编号需要按照大小升序排列,分班记录中第一个编号小的排在第一行
- 如果只有一个班的小朋友 第二行为空
- 如果输入不符合要求输出字符串
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
思路
解题思路:
-
读取输入:首先通过
fgets
函数获取用户输入的一行字符串,然后使用strtok
函数将其按照空格分割成一个个包含编号和是否同班标志的token(例如:“1/N”、"2/Y"等),并将这些token存入临时数组中。 -
初始化学生结构体数组:根据临时数组中的信息,利用
sscanf
函数将每个token解析为小朋友的编号(id)和是否同班(isClass)标志,并存储到Students
结构体数组stu
中。 -
判断首位合法性:检查首位小朋友是否与前一位小朋友同班。由于没有前一位小朋友,若首位标记为“Y”,则输入非法,输出"ERROR"并结束程序。
-
分配班级:遍历整个
stu
数组,对于每个小朋友:- 首位小朋友直接划归到班级1;
- 若当前小朋友与前一位小朋友同班,则将其划归到前一位所在的班级;
- 若当前小朋友与前一位小朋友不同班,则将其划归到另一个班级。
在这个过程中,用两个整数数组
class1
和class2
分别记录两个班级的小朋友编号。 -
排序输出:对两个班级数组进行升序排序,这里使用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]; // 临时存储每个tokenint 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);}// 检查首位小朋友是否与前一位小朋友同班(实际上没有前一位),若同班则输入非法,输出ERRORif (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为1continue;}// 若当前小朋友与前一位小朋友同班,则将其划分到同一班级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;
}
文章目录
- 题目
- 输入
- 输出
- 示例一
- 输入
- 输出
- 说明
- 示例二
- 输入
- 输出
- 思路
- 代码
这篇关于分班问题 、幼儿园分班(C语言)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!