L1-030 一帮一
本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中,将名次最靠前的学生与名次最靠后的异性学生分为一组。
输入格式:
输入第一行给出正偶数N
(≤50),即全班学生的人数。此后N
行,按照名次从高到低的顺序给出每个学生的性别(0代表女生,1代表男生)和姓名(不超过8个英文字母的非空字符串),其间以1个空格分隔。这里保证本班男女比例是1:1,并且没有并列名次。
输出格式:
每行输出一组两个学生的姓名,其间以1个空格分隔。名次高的学生在前,名次低的学生在后。小组的输出顺序按照前面学生的名次从高到低排列。
输入样例:
8 0 Amy 1 Tom 1 Bill 0 Cindy 0 Maya 1 John 1 Jack 0 Linda
输出样例:
Amy Jack Tom Linda Bill Maya Cindy John
#include<stdio.h> int main(){ int n,sex[50],flag[50]={0}; char name[50][20]; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d %s",&sex[i],name[i]); } for(int i=0;i<n;i++){ for(int j=n-1;j>=0;j--){ if(sex[i]!=sex[j] && flag[i]==0 && flag[j]==0){ printf("%s %s\n",name[i],name[j]); flag[i]=1;//已匹配 flag[j]=1; } } } return 0; }
sex[i]
),需要使用 &
来获取变量的地址。name[i]
),不需要使用 &
,因为数组名已经是数组首元素的地址。name[50][20]——二维数组
name
可以存储 50 个字符串,每个字符串最多 19 个字符(留一个位置给 \0
,字符串的结束标志)。这个声明相当于一个指向字符数组的指针数组,name[i]
就表示数组中的第 i
个字符串。
为什么使用 name[i]
而不是 name
?
- name 是一个二维数组的名字,它表示指向第一个字符串的指针(char[20] 类型)。如果你写 name,实际上它指向的是 name[0](即第一个字符串的数组)。
- name[i] 是一个字符数组,表示数组中的第 i 个字符串。因此,name[i] 就是一个 char[20] 类型的数组,表示一个长度为 20 的字符数组,用来存储第 i 个人的名字。
- 当你用
scanf("%s", name[i]);
时,scanf
会把输入的字符串存储到name[i]
这个字符数组中。由于name[i]
本身是一个字符数组,它实际上是一个指向字符数组的指针,scanf
可以将输入的字符串直接存储在这个数组中。
为什么不直接使用 name
?
如果你写 scanf("%s", name);
,那么 name
作为一个二维数组表示的是一个指向第一个字符串的指针。这样 scanf
就会将输入的字符串存储到 name[0]
中,而不是 name[i]
中。因此,你需要用 name[i]
来指定要存储哪个字符串。
关键点:
用flag数组标记已匹配的同学,防止重复匹配。