diff --git a/【实践课外】16.结构体2/7-1 一帮一.c b/【实践课外】16.结构体2/7-1 一帮一.c new file mode 100644 index 0000000..14a01b9 --- /dev/null +++ b/【实践课外】16.结构体2/7-1 一帮一.c @@ -0,0 +1,44 @@ +#include + +#define FEMALE (0) +#define MALE (1) + +struct student { + int gender; // 0 is female, 1 is male + char name[10]; // the problem promises that the name will not exceed 8 characters + int has_group; +}; + +int n, pos[2]; +struct student students[55]; // the problem promises that the number of students will not exceed 50 + +int main() { + scanf("%d", &n); + + pos[FEMALE] = pos[MALE] = n; + + for (int i = 0; i < n; i++) { + scanf("%d %s", &students[i].gender, students[i].name); + } + + for (int i = 0; i < n; i++) { + if (students[i].has_group) continue; + + int current_gender = students[i].gender, + target_gender = current_gender ^ 1; + + for (pos[target_gender]--; pos[target_gender] >= 0; pos[target_gender]--) { + if (students[pos[target_gender]].gender == target_gender + && !students[pos[target_gender]].has_group) { + students[pos[target_gender]].has_group = 1; + students[i].has_group = 1; + + printf("%s %s\n", students[i].name, students[pos[target_gender]].name); + + break; + } + } + } + + return 0; +} diff --git a/【实践课外】16.结构体2/7-1 一帮一.md b/【实践课外】16.结构体2/7-1 一帮一.md new file mode 100644 index 0000000..00ec891 --- /dev/null +++ b/【实践课外】16.结构体2/7-1 一帮一.md @@ -0,0 +1,32 @@ +# 7-5 一帮一 + +“一帮一学习小组”是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组。本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中,将名次最靠前的学生与名次最靠后的**异性**学生分为一组。 + +### 输入格式: + +输入第一行给出正偶数`N`($$\le$$50),即全班学生的人数。此后`N`行,按照名次从高到低的顺序给出每个学生的性别(0代表女生,1代表男生)和姓名(不超过8个英文字母的非空字符串),其间以1个空格分隔。这里保证本班男女比例是1:1,并且没有并列名次。 + +### 输出格式: + +每行输出一组两个学生的姓名,其间以1个空格分隔。名次高的学生在前,名次低的学生在后。小组的输出顺序按照前面学生的名次从高到低排列。 + +### 输入样例: +```in +8 +0 Amy +1 Tom +1 Bill +0 Cindy +0 Maya +1 John +1 Jack +0 Linda +``` + +### 输出样例: +```out +Amy Jack +Tom Linda +Bill Maya +Cindy John +``` diff --git a/【实践课外】16.结构体2/7-2 考试座位号.c b/【实践课外】16.结构体2/7-2 考试座位号.c new file mode 100644 index 0000000..36c6685 --- /dev/null +++ b/【实践课外】16.结构体2/7-2 考试座位号.c @@ -0,0 +1,34 @@ +#include + +struct student { + char id[20]; // the problem promises that the id will not exceed 16 characters + int seat1, seat2; +}; + +int n, m; +struct student students[1005]; // the problem promises that the number of students will not exceed 1000 + +int main() { + scanf("%d", &n); + + for (int i = 0; i < n; i++) { + scanf("%s %d %d", students[i].id, &students[i].seat1, &students[i].seat2); + } + + scanf("%d", &m); + + for (int i = 0; i < m; i++) { + int seat; + scanf("%d", &seat); + + for (int j = 0; j < n; j++) { + if (students[j].seat1 == seat) { + printf("%s %d\n", students[j].id, students[j].seat2); + + break; + } + } + } + + return 0; +} diff --git a/【实践课外】16.结构体2/7-2 考试座位号.md b/【实践课外】16.结构体2/7-2 考试座位号.md new file mode 100644 index 0000000..9264b81 --- /dev/null +++ b/【实践课外】16.结构体2/7-2 考试座位号.md @@ -0,0 +1,32 @@ +# 7-6 考试座位号 + +“一帮一学习小组”是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组。本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中,将名次最靠前的学生与名次最靠后的**异性**学生分为一组。 + +### 输入格式: + +输入第一行给出正偶数`N`($$\le$$50),即全班学生的人数。此后`N`行,按照名次从高到低的顺序给出每个学生的性别(0代表女生,1代表男生)和姓名(不超过8个英文字母的非空字符串),其间以1个空格分隔。这里保证本班男女比例是1:1,并且没有并列名次。 + +### 输出格式: + +每行输出一组两个学生的姓名,其间以1个空格分隔。名次高的学生在前,名次低的学生在后。小组的输出顺序按照前面学生的名次从高到低排列。 + +### 输入样例: +```in +8 +0 Amy +1 Tom +1 Bill +0 Cindy +0 Maya +1 John +1 Jack +0 Linda +``` + +### 输出样例: +```out +Amy Jack +Tom Linda +Bill Maya +Cindy John +``` diff --git a/【实践课外】16.结构体2/7-3 新键表输出.c b/【实践课外】16.结构体2/7-3 新键表输出.c new file mode 100644 index 0000000..f0ca73a --- /dev/null +++ b/【实践课外】16.结构体2/7-3 新键表输出.c @@ -0,0 +1,21 @@ +#include + +int main() { + int x, flag = 0; + + while (scanf("%d", &x) != EOF && x != -1) { + if (x % 2 == 1) { + if (flag == 1) { + printf(" "); + } else { + flag = 1; + } + + printf("%d", x); + } + } + + printf("\n"); + + return 0; +} diff --git a/【实践课外】16.结构体2/7-3 新键表输出.md b/【实践课外】16.结构体2/7-3 新键表输出.md new file mode 100644 index 0000000..3eddf2f --- /dev/null +++ b/【实践课外】16.结构体2/7-3 新键表输出.md @@ -0,0 +1,17 @@ +# 7-3 新键表输出 + +有一个单向链表,头指针为L,结点的数据域是一个整数,将链表L中奇数值的结点重新组成一个新的链表NEW,并输出新建链表。 + +输入格式:输入若干个整数,以-1结束输入 + +输出格式:数值之间以一个空格分隔,最后一个数值后面没有空格 + +### 输入样例: +```in +1 2 3 4 5 6 7 -1 +``` + +### 输出样例: +```out +1 3 5 7 +``` diff --git a/【实践课外】16.结构体2/7-4 可怕的素质.c b/【实践课外】16.结构体2/7-4 可怕的素质.c new file mode 100644 index 0000000..8a29b4a --- /dev/null +++ b/【实践课外】16.结构体2/7-4 可怕的素质.c @@ -0,0 +1,76 @@ +#include + +struct node { + int x; + struct node *next; +}; + +int n; +struct node *head; + +void insert_after(struct node *cur, int pos, int x) { + if (cur->next == NULL) { + struct node *nxt = (struct node *)malloc(sizeof(struct node)); + nxt->x = x; + nxt->next = NULL; + cur->next = nxt; + + return; + } + + if (pos == cur->x) { + struct node *nxt = (struct node *)malloc(sizeof(struct node)); + nxt->x = x; + nxt->next = cur->next; + cur->next = nxt; + + return; + } + + insert_after(cur->next, pos, x); +} + +void cleanup() { + struct node *ptr = head; + + while (ptr != NULL) { + struct node *tmp = ptr; + ptr = ptr->next; + free(tmp); + } +} + +int main() { + head = (struct node *)malloc(sizeof(struct node)); + + scanf("%d", &n); + + for (int i = 1, x; i <= n; i++) { + scanf("%d", &x); + + insert_after(head, x, i); + } + + int flag = 0; + struct node *ptr = head; + + while (ptr != NULL) { + if (ptr->x != 0) { + if (flag == 1) { + printf(" "); + } else { + flag = 1; + } + + printf("%d", ptr->x); + } + + ptr = ptr->next; + } + + printf("\n"); + + cleanup(); + + return 0; +} diff --git a/【实践课外】16.结构体2/7-4 可怕的素质.md b/【实践课外】16.结构体2/7-4 可怕的素质.md new file mode 100644 index 0000000..679fa9d --- /dev/null +++ b/【实践课外】16.结构体2/7-4 可怕的素质.md @@ -0,0 +1,31 @@ +# 7-4 可怕的素质 + +亚克星球上的人的素质跟我们福大人比起来,可以说是一个天上,一个地下了。他们去食堂吃饭的时候,很多人都不好好的排队,而是排在某个熟人的后面,或者直接就插到队伍的最前面。这让食堂的工作人员很是恼火。 + +### 输入格式: + +第一行包含一个整数n(0 + +struct node { + char name[105]; + int age; +}; + +int n, k, flag; +struct node stu[105]; + +int main() { + scanf("%d", &n); + + for (int i = 0; i < n; i++) { + scanf("%s %d", stu[i].name, &stu[i].age); + } + + scanf("%d", &k); + + for (int i = 0; i < n; i++) { + if (stu[i].age != k) { + if (flag == 1) { + printf(" "); + } else { + flag = 1; + } + + printf("%s", stu[i].name); + } + } + + return 0; +} diff --git a/【实践课外】16.结构体2/7-5 找出同龄者.md b/【实践课外】16.结构体2/7-5 找出同龄者.md new file mode 100644 index 0000000..f47f0c8 --- /dev/null +++ b/【实践课外】16.结构体2/7-5 找出同龄者.md @@ -0,0 +1,32 @@ +# 7-5 找出同龄者 + +最近,小明开始班级大搜索,他已经知道了班级里每个人的年龄,并且把他们排成了一队,他将从排好队的人里按顺序把和自己同龄的人找出来,并请这些同龄人出队。 + +### 输入格式: + +第一行输入一个N(0 + +struct node { + int id, rank, pre_id, suf_id; + double height; +}; + +int n; +struct node p[1005]; + +int cmp_by_height(const void *a, const void *b) { + struct node *pa = (struct node *)a, + *pb = (struct node *)b; + + if (pa->height != pb->height) { + return pa->height < pb->height ? 1 : -1; + } + + return 0; +} + +int cmp_by_id(const void *a, const void *b) { + struct node *pa = (struct node *)a, + *pb = (struct node *)b; + + return pa->id - pb->id; +} + +int main() { + scanf("%d", &n); + + for (int i = 1; i <= n; i++) { + scanf("%lf", &p[i].height); + p[i].id = i; + } + + qsort(p + 1, n, sizeof(struct node), cmp_by_height); + + for (int i = 1; i <= n; i++) { + p[i].rank = i; + p[i].pre_id = i - 1 < 1 ? 0 : p[i - 1].id; + p[i].suf_id = i + 1 > n ? 0 : p[i + 1].id; + } + + qsort(p + 1, n, sizeof(struct node), cmp_by_id); + + for (int i = 1; i <= n; i++) { + printf("%d %d %d\n", p[i].rank, p[i].pre_id, p[i].suf_id); + } + + return 0; +} diff --git a/【实践课外】16.结构体2/7-6 排队.md b/【实践课外】16.结构体2/7-6 排队.md new file mode 100644 index 0000000..af45e77 --- /dev/null +++ b/【实践课外】16.结构体2/7-6 排队.md @@ -0,0 +1,41 @@ +# 7-6 排队 + +晨跑小组决定从今天开始晨跑了,为了使晨跑的队伍看上去比较整齐,于是小组成员决定按身高从高到低排成一列。现在已知晨跑小组每个成员的身高。小组成员们都想知道自己排在第几位,前面和后面相邻的人分别是谁。请编写程序帮助他们实现吧。 + +### 输入格式: + +输入第一行包括一个正整数N(1<=N<=1000),表示晨跑小组的人数。 + +接下来一行有N个浮点数Ai,Ai表示第i个人的身高(1<=i<=N)。(数据中没有两个人身高相同的情况)。 + +### 输出格式: + +输出N行,每行有三个数据Ri,Fi,Bi。 + +Ri表示第i个人排在第几位。 + +Fi表示第 i个人前面相邻人的编号,如果前面没有人,输出0。 + +Bi表示第i个人后面相邻人的编号,如果后面没有人,输出0。 + +### 输入样例: + + +```in +5 +178.5 +177.4 +165.4 +164.6 +173.3 +``` + +### 输出样例: + +```out +1 0 2 +2 1 5 +4 5 4 +5 3 0 +3 2 3 +``` diff --git a/【实践课外】16.结构体2/7-7 军训.c b/【实践课外】16.结构体2/7-7 军训.c new file mode 100644 index 0000000..dc93979 --- /dev/null +++ b/【实践课外】16.结构体2/7-7 军训.c @@ -0,0 +1,53 @@ +#include +#include + +void train_soldiers(int n) { + int *soldiers = (int *)malloc(n * sizeof(int)); + int remaining = n; + int step = 2; + + for (int i = 0; i < n; i++) { + soldiers[i] = i + 1; + } + + while (remaining > 3) { + int index = 0; + + for (int i = 0; i < remaining; i++) { + if ((i + 1) % step != 0) { + soldiers[index++] = soldiers[i]; + } + } + + remaining = index; + step = (step == 2) ? 3 : 2; + } + + for (int i = 0; i < remaining; i++) { + printf("%d", soldiers[i]); + + if (i < remaining - 1) { + printf(" "); + } + } + + printf("\n"); + + free(soldiers); +} + +int main() { + int t; + + scanf("%d", &t); + + while (t--) { + int n; + + scanf("%d", &n); + + train_soldiers(n); + } + + return 0; +} diff --git a/【实践课外】16.结构体2/7-7 军训.md b/【实践课外】16.结构体2/7-7 军训.md new file mode 100644 index 0000000..defebda --- /dev/null +++ b/【实践课外】16.结构体2/7-7 军训.md @@ -0,0 +1,30 @@ +# 7-7 军训 + +某部队进行新兵队列训练,将新兵从1开始按顺序依次编号,并排成一行横队。训练的规则如下:从头开始1至2报数,凡报到2的新兵出列,剩下的新兵向小序号方向靠拢;再从头开始进行1至3报数,凡报到3的新兵出列,剩下的向小序号方向靠拢;继续从头开始进行1至2报数。。。;如此这样一直进行,直到剩下的人数不超过3人为止。 + +### 输入格式: + +第一行输入一个整数T(0 + +#define N 100005 + +int val[N], pre[N], nxt[N], idx; + +void init() { + // 0 是开头(虚) + nxt[0] = 1; + // 1 是结尾(虚) + pre[1] = 0; + idx = 2; +} + +void insert_pre(int k, int x) { + val[idx] = x; + pre[idx] = pre[k]; + nxt[idx] = k; + nxt[pre[k]] = idx; + pre[k] = idx; + idx++; +} + +void insert_nxt(int k, int x) { + val[idx] = x; + nxt[idx] = nxt[k]; + pre[idx] = k; + pre[nxt[k]] = idx; + nxt[k] = idx; + idx++; +} + +void remove_node(int k) { + nxt[pre[k]] = nxt[k]; + pre[nxt[k]] = pre[k]; +} + +int main() { + init(); + + int m; + + scanf("%d", &m); + + while (m--) { + char op[3]; + int k, x; + + scanf("%s", op); + + if (op[0] == 'L') { + scanf("%d", &x); + insert_pre(nxt[0], x); + } else if (op[0] == 'R') { + scanf("%d", &x); + insert_nxt(pre[1], x); + } else if (op[0] == 'D') { + scanf("%d", &k); + remove_node(k + 1); + } else { // op[0] == 'I' + scanf("%d %d", &k, &x); + + if (op[1] == 'L') { + insert_pre(k + 1, x); + } else { // op[1] == 'R' + insert_nxt(k + 1, x); + } + } + } + + for (int i = nxt[0]; i != 1; i = nxt[i]) { + printf("%d ", val[i]); + } + + return 0; +} diff --git a/【实践课外】16.结构体2/7-8 双链表.md b/【实践课外】16.结构体2/7-8 双链表.md new file mode 100644 index 0000000..61dd42c --- /dev/null +++ b/【实践课外】16.结构体2/7-8 双链表.md @@ -0,0 +1,65 @@ +# 7-8 双链表 + +实现一个双链表,双链表初始为空,支持 5 种操作: + +1.在最左侧插入一个数; +2.在最右侧插入一个数; +3.将第 k 个插入的数删除; +4.在第 k 个插入的数左侧插入一个数; +5.在第 k 个插入的数右侧插入一个数 + +现在要对该链表进行 M 次操作,进行完所有操作后,从左到右输出整个链表。 + +注意:题目中第 k 个插入的数并不是指当前链表的第 k 个数。例如操作过程中一共插入了 n 个数,则按照插入的时间顺序,这 n 个数依次为:第 1 个插入的数,第 2 个插入的数,…第 n 个插入的数。 + + + +### 输入格式: + +第一行包含整数 M,表示操作次数。 + +接下来 M 行,每行包含一个操作命令,操作命令可能为以下几种: + +1.L x,表示在链表的最左端插入数 x。 +2.R x,表示在链表的最右端插入数 x。 +3.D k,表示将第 k 个插入的数删除。 +4.IL k x,表示在第 k 个插入的数左侧插入一个数。 +5.IR k x,表示在第 k 个插入的数右侧插入一个数。 + + + +### 输出格式: + +共一行,将整个链表从左到右输出。 + +### 数据范围: +$$1≤M≤100000 $$ +所有操作保证合法。 + + + +### 输入样例: + +在这里给出一组输入。例如: + +```in +10 +R 7 +D 1 +L 3 +IL 2 10 +D 3 +IL 2 7 +L 8 +R 9 +IL 4 7 +IR 2 2 +``` + +### 输出样例: + +在这里给出相应的输出。例如: + +```out +8 7 7 3 2 9 +``` diff --git a/【实践课外】16.结构体2/7-9 通讯录的录入与显示.c b/【实践课外】16.结构体2/7-9 通讯录的录入与显示.c new file mode 100644 index 0000000..c28be44 --- /dev/null +++ b/【实践课外】16.结构体2/7-9 通讯录的录入与显示.c @@ -0,0 +1,34 @@ +#include + +struct contact { + char name[15], birthday[15], gender, tel[20], phone[20]; +}; + +int n, k; +struct contact contacts[15]; + +int main() { + scanf("%d", &n); + + for (int i = 0; i < n; i++) { + scanf("%s %s %c %s %s\n", contacts[i].name, contacts[i].birthday, &contacts[i].gender, contacts[i].tel, contacts[i].phone); + } + + scanf("%d", &k); + + for (int i = 0; i < k; i++) { + int x; + + scanf("%d", &x); + + if (x < 0 || x >= n) { + printf("Not Found\n"); + + continue; + } + + printf("%s %s %s %c %s\n", contacts[x].name, contacts[x].tel, contacts[x].phone, contacts[x].gender, contacts[x].birthday); + } + + return 0; +} diff --git a/【实践课外】16.结构体2/7-9 通讯录的录入与显示.md b/【实践课外】16.结构体2/7-9 通讯录的录入与显示.md new file mode 100644 index 0000000..5268404 --- /dev/null +++ b/【实践课外】16.结构体2/7-9 通讯录的录入与显示.md @@ -0,0 +1,29 @@ +# 7-9 通讯录的录入与显示 + +通讯录中的一条记录包含下述基本信息:朋友的姓名、出生日期、性别、固定电话号码、移动电话号码。 +本题要求编写程序,录入$$N$$条记录,并且根据要求显示任意某条记录。 + +### 输入格式: + +输入在第一行给出正整数$$N$$($$\le$$10);随后$$N$$行,每行按照格式`姓名 生日 性别 固话 手机`给出一条记录。其中`姓名`是不超过10个字符、不包含空格的非空字符串;生日按`yyyy/mm/dd`的格式给出年月日;性别用`M`表示“男”、`F`表示“女”;`固话`和`手机`均为不超过15位的连续数字,前面有可能出现`+`。 + +在通讯录记录输入完成后,最后一行给出正整数$$K$$,并且随后给出$$K$$个整数,表示要查询的记录编号(从0到$$N-1$$顺序编号)。数字间以空格分隔。 + +### 输出格式: + +对每一条要查询的记录编号,在一行中按照`姓名 固话 手机 性别 生日`的格式输出该记录。若要查询的记录不存在,则输出`Not Found`。 + +### 输入样例: +```in +3 +Chris 1984/03/10 F +86181779452 13707010007 +LaoLao 1967/11/30 F 057187951100 +8618618623333 +QiaoLin 1980/01/01 M 84172333 10086 +2 1 7 +``` + +### 输出样例: +```out +LaoLao 057187951100 +8618618623333 F 1967/11/30 +Not Found +```