題目
幼兒園兩個班的小朋友排隊時混在了一起,每個小朋友都知道自己跟前面一個小朋友是不是同班,請你幫忙把同班的小朋友找出來
小朋友的編號為整數,與前面一個小朋友同班用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;
}
文章目錄
- 題目
- 輸入
- 輸出
- 示例一
- 輸入
- 輸出
- 說明
- 示例二
- 輸入
- 輸出
- 思路
- 代碼