1
0
mirror of https://github.com/renbaoshuo/202401-programming-assignments.git synced 2024-12-16 15:44:39 +00:00

【实践课外】16.结构体2

This commit is contained in:
Baoshuo Ren 2024-12-16 23:44:08 +08:00
parent f4a8b739f9
commit a09fced980
Failed to extract signature
18 changed files with 732 additions and 0 deletions

View File

@ -0,0 +1,44 @@
#include <stdio.h>
#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;
}

View File

@ -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
```

View File

@ -0,0 +1,34 @@
#include <stdio.h>
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;
}

View File

@ -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
```

View File

@ -0,0 +1,21 @@
#include <stdio.h>
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;
}

View File

@ -0,0 +1,17 @@
# 7-3 新键表输出
有一个单向链表头指针为L结点的数据域是一个整数将链表L中奇数值的结点重新组成一个新的链表NEW并输出新建链表。
输入格式:输入若干个整数,以-1结束输入
输出格式:数值之间以一个空格分隔,最后一个数值后面没有空格
### 输入样例:
```in
1 2 3 4 5 6 7 -1
```
### 输出样例:
```out
1 3 5 7
```

View File

@ -0,0 +1,76 @@
#include <stdio.h>
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;
}

View File

@ -0,0 +1,31 @@
# 7-4 可怕的素质
亚克星球上的人的素质跟我们福大人比起来,可以说是一个天上,一个地下了。他们去食堂吃饭的时候,很多人都不好好的排队,而是排在某个熟人的后面,或者直接就插到队伍的最前面。这让食堂的工作人员很是恼火。
### 输入格式:
第一行包含一个整数n0<n<1000,表示有n个亚克星球上的人去食堂吃饭
接下来n行每行1个整数x表示第i( i从1~n )个人排在了x的后面当x为0时表示第i个人排在了最前面。
### 输出格式:
输出仅一行包括n个数以空格作为分隔符最后一个数的后面没有空格。表示这n个人最后是排成了怎样的队伍。
### 输入样例:
```in
3
0
0
2
```
### 输出样例:
```out
2 3 1
```

View File

@ -0,0 +1,33 @@
#include <stdio.h>
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;
}

View File

@ -0,0 +1,32 @@
# 7-5 找出同龄者
最近,小明开始班级大搜索,他已经知道了班级里每个人的年龄,并且把他们排成了一队,他将从排好队的人里按顺序把和自己同龄的人找出来,并请这些同龄人出队。
### 输入格式:
第一行输入一个N0<n<100表示有N个学生
接下来有N行每行两个数据分别表示某个同学的名字和年龄
最后一行包含一个整数,表示小明的年龄。
### 输出格式:
输出仅一行,包含若干学生的姓名,姓名与姓名之间用空格分隔,最后一个名字的末尾没有空格。表示小明的同龄者出队后,队伍中学生的排序。
### 输入样例:
```in
3
张三 20
李四 22
王五 15
22
```
### 输出样例:
```out
张三 王五
```

View File

@ -0,0 +1,52 @@
#include <stdio.h>
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;
}

View File

@ -0,0 +1,41 @@
# 7-6 排队
晨跑小组决定从今天开始晨跑了,为了使晨跑的队伍看上去比较整齐,于是小组成员决定按身高从高到低排成一列。现在已知晨跑小组每个成员的身高。小组成员们都想知道自己排在第几位,前面和后面相邻的人分别是谁。请编写程序帮助他们实现吧。
### 输入格式:
输入第一行包括一个正整数N1<=N<=1000表示晨跑小组的人数。
接下来一行有N个浮点数AiAi表示第i个人的身高1<=i<=N数据中没有两个人身高相同的情况
### 输出格式:
输出N行每行有三个数据RiFiBi。
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
```

View File

@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
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;
}

View File

@ -0,0 +1,30 @@
# 7-7 军训
某部队进行新兵队列训练将新兵从1开始按顺序依次编号并排成一行横队。训练的规则如下从头开始1至2报数凡报到2的新兵出列剩下的新兵向小序号方向靠拢再从头开始进行1至3报数凡报到3的新兵出列剩下的向小序号方向靠拢继续从头开始进行1至2报数。。。如此这样一直进行直到剩下的人数不超过3人为止。
### 输入格式:
第一行输入一个整数T0<T<100表示共有T组新兵进行训练
接下来有T行每行输入一个整数N0<N<=5000代表这组新兵的人数
### 输出格式:
输出共T行每行按照编号从小到大的顺序输出每组新兵进行训练后剩下的新兵编号编号之间以空格分隔每行末尾有一个换行符。
### 输入样例:
```in
2
20
40
```
### 输出样例:
```out
1 7 19
1 19 37
```

View File

@ -0,0 +1,76 @@
#include <stdio.h>
#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;
}

View File

@ -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
```

View File

@ -0,0 +1,34 @@
#include <stdio.h>
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;
}

View File

@ -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
```