【数据结构与算法】学习笔记-《算法笔记》-8

排序

选择

排序
学习了最常用的简单选择哎嘘,复杂度高达O(n2)
示例:

插入排序

学习了最直观的直接插入排序
示例:

sort函数的应用

推荐直接使用C语言中的库函数qsort或是C++中的sort函数进行代码编写
sort函数的头文件为< algorithm>
它的使用必须加上

#include<algorithm>
using namespace std;

函数格式如下:

sort(首元素地址(必填),尾元素地址的下一个地址(必填),比较函数(非必填));

如果不写比较函数,则默认对前面给出的区间进行递增排序
可以对int/float/char型等数据类型进行排序
示例:

#include <cstdio>
#include <algorithm>
using namespace std;


int main()
{
	int a[6] = { 9,4,2,5,6,-1 };//从小到大排序a[0]到a[3]
	sort(a, a + 4);
	for (int i = 0; i < 6; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
	//从小到大排序a[0]到a[5]
	sort(a, a + 6);
	for (int i = 0; i < 6; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

如何实现比较函数CMP

sort函数的第三个可选参数是compare函数(一般写作cmp函数),用于人为制定比较规则比较结构体等本身没有大小关系和可比性的类型。
分别学习对基本数据类型、结构体类型、STL容器进行自定义规则排序时cmp的写法:

  1. 基本数据类型数组的排序
    如果cmp不填,默认是从小到大排序,想要实现从大到小排序,则需使用cmp“告诉”sort何时交换元素
    示例:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

bool cmp(int a, int b) {
	return a > b;//理解为当a>b时把a放在b前面
}

int main()
{
	int a[6] = { 9,4,2,5,6,-1 };
	sort(a, a + 6,cmp);
	for (int i = 0; i < 6; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}
  1. 结构体数组的排序
    定义了如下的结构体:
struct node {
	int x, y;
}ssd[10];

1).一级排序
如果想将ssd数组按照x从大到小进行排序,可以这样写cmp函数

bool cmp(node a, node b) {
	return a.x > b.x;//理解为当a>b时把a放在b前面
}

示例:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

struct node {
	int x, y;
}ssd[10];

bool cmp(node a, node b) {
	return a.x > b.x;//理解为当a>b时把a放在b前面
}

int main()
{
	ssd[0].x = 2;
	ssd[0].y = 2;
	ssd[1].x = 1;
	ssd[1].y = 3;
	ssd[2].x = 3;
	ssd[2].y = 1;
	sort(ssd, ssd + 3,cmp);
	for (int i = 0; i < 3; i++)
	{
		printf("%d %d\n", ssd[i].x,ssd[i].y);
	}
	return 0;
}

输出:

3 1
2 2
1 3
请按任意键继续. . .

2).二级排序
先按照x从大到小排序,但当x相等的情况下,按照y从小到大排序,那么cmp设置为:

bool cmp(node a, node b) {
	if (a.x != b.x)
		return a.x > b.x;
	else
		return a.y < b.y;
}

示例:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

struct node {
	int x, y;
}ssd[10];

bool cmp(node a, node b) {
	if (a.x != b.x)
		return a.x > b.x;
	else
		return a.y < b.y;
}

int main()
{
	ssd[0].x = 2;
	ssd[0].y = 2;
	ssd[1].x = 1;
	ssd[1].y = 3;
	ssd[2].x = 2;
	ssd[2].y = 1;
	sort(ssd, ssd + 3,cmp);
	for (int i = 0; i < 3; i++)
	{
		printf("%d %d\n", ssd[i].x,ssd[i].y);
	}
	return 0;
}

输出:

2 1
2 2
1 3
请按任意键继续. . .
  1. 容器的排序
    在STL标准容器中,只有vector、string、deque是可以用sort的,这是因为像set、map这种容器是用红黑树实现的,元素本身有序,故不允许使用sort排序。
    以vector为例
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

struct node {
	int x, y;
}ssd[10];

bool cmp(int a, int b) {
	return a > b;//由于vector中的元素为int型,因此仍然是Int的比较
}

int main()
{
	vector<int> vi;
	vi.push_back(3);
	vi.push_back(1);
	vi.push_back(2);
	sort(vi.begin(), vi.end(), cmp);//对整个vector排序
	for (int i = 0; i < 3; i++)
	{
		printf("%d ", vi[i]);
	}
	return 0;
}

输出:

3 2 1 请按任意键继续. . .

看string的排序:

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;

int main()
{
	string str[3] = { "bbbb","cc","aaa" };
	sort(str, str + 3);//将string型数组按字典序从小到大输出
	for (int i = 0; i < 3; i++)
	{
		//printf("%s \n",str[i]);//注意这里不能用printf,至于为什么,目前还不知道==
		cout << str[i] << endl;
	}
	return 0;
}

注意这里不能用printf,至于为什么,目前还不知道
输出:

aaa
bbbb
cc
请按任意键继续. . .

如果要换成从小到大排序,则为

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;

bool cmp(string str1,string str2) {
	return str1.length() < str2.length();
}

int main()
{
	string str[3] = { "bbbb","cc","aaa" };
	sort(str, str + 3,cmp);//将string型数组按字典序从小到大输出
	for (int i = 0; i < 3; i++)
	{
		//printf("%s \n",str[i]);//注意这里不能用printf,至于为什么,目前还不知道==
		cout << str[i] << endl;
	}
	return 0;
}

输出:

cc
aaa
bbbb
请按任意键继续. . .

学生排名的实现

学生个体排名规则:分数不同的排名不同,分数相同给的排名相同但占用一个排位,有两种方法实现排名的计算:(数组排序完后)

  1. 如果当前个体的分数等于上一个个体的分数,排名等于上一个的排名,否则排名等于数组下标+1;
  2. 如果题目不一定要真的记录排名而只要输出:令int型变量r的初值为1,然后遍历所有个体,如果当前个体不是第一个个体且当前个体的分数不等于上一个个体的分数,则r等于数组下表加1。这样的做法适用于需要输出的信息过多,导致第一种方法代码冗长的情况。
    示例:
    n个考场,给出各考场中考生的准考证号和分数,要求所有考生按分数从高到低排序,并按顺序输出所有考生的准考证号、排名、考场号以及考场内排名;
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;

struct student {
	long long  number;
	int score;
	int num;
	int rank0;
	int rank1;
}stu[100];

bool cmp(student a,student b) {
	if (a.score == b.score)
		return a.number < b.number;
	else
		return a.score > b.score;
}

//n个考场,给出各考场中考生的准考证号和分数,
//要求所有考生按分数从高到低排序,
//并按顺序输出所有考生的准考证号、排名、考场号以及考场内排名;

int main()
{
	int total = 0;//考场学生数
	int alltotal = 0;//学生总数
	int n;//考场数
	int k = 0;//学生数组号
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		int temp = k;
		scanf("%d", &total);
		for (int j = 0; j < total; j++)
		{
			scanf("%lld%d", &stu[k].number, &stu[k].score);
			stu[k].num = i + 1;
			k++;
		}
		alltotal += total;
		sort(stu + temp, stu + temp + total + 1, cmp);
		stu[temp].rank0 = 1;
		for (int j = temp+1; j < total+temp; j++)
		{
			if (stu[j].score == stu[j - 1].score)
			{
				stu[j].rank0 = stu[j - 1].rank0;
			}
			else
			{
				stu[j].rank0 = j-temp + 1;
			}
		}
	}
	printf("%d\n", alltotal);
	sort(stu, stu + alltotal+1,cmp);
	stu[0].rank1 = 1;
	printf("%lld %d %d %d\n", stu[0].number, stu[0].rank1, stu[0].num, stu[0].rank0);
	for (int j = 1; j < alltotal; j++)
	{
		if (stu[j].score == stu[j - 1].score)
		{
			stu[j].rank1 = stu[j - 1].rank1;
		}
		else
		{
			stu[j].rank1 = j + 1;
		}
		printf("%lld %d %d %d\n", stu[j].number, stu[j].rank1, stu[j].num, stu[j].rank0);
	}
	return 0;
}

输入:

2
5
8888001 95
8888005 100
8888003 95
8888002 77
8888004 85
4
8888013 65
8888011 25
8888014 100
8888012 85

输出

2
5
8888001 95
8888005 100
8888003 95
8888002 77
8888004 85
4
8888013 65
8888011 25
8888014 100
8888012 85

课本代码示例:

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;

struct student {
	char id[15];//准考证号
	int score;//分数
	int location_number;//考场号
	int location_rank;//考场内排名
}stu[100];

bool cmp(student a,student b) {
	if (a.score != b.score)
		return a.score > b.score;
	else
		return strcmp(a.id,b.id)<0;
}

//n个考场,给出各考场中考生的准考证号和分数,
//要求所有考生按分数从高到低排序,
//并按顺序输出所有考生的准考证号、排名、考场号以及考场内排名;

int main()
{
	int k, num = 0;//num为学生总数
	int n;//考场数
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &k);//该考场内人数
		for (int j = 0; j < k; j++)
		{
			scanf("%s%d", &stu[num].id, &stu[num].score);
			stu[num].location_number = i ;
			num++;
		}
		sort(stu + num-k, stu + num, cmp);
		stu[num-k].location_rank = 1;
		for (int j = num-k+1; j < num; j++)
		{
			if (stu[j].score == stu[j - 1].score)
			{
				stu[j].location_rank = stu[j - 1].location_rank;
			}
			else
			{
				stu[j].location_rank = j-(num-k) + 1;
			}
		}
	}
	printf("%d\n", num);
	sort(stu, stu + num,cmp);
	int r = 1;
	for (int j = 0; j < num; j++)
	{
		if (j>0&&stu[j].score != stu[j - 1].score)
		{
			r = j + 1;
			//stu[j].rank1 = stu[j - 1].rank1;
		}
		printf("%s %d %d %d\n", stu[j].id, r, stu[j].location_number, stu[j].location_rank);
	}
	return 0;
}

可以学习的几点:

  1. cmp函数的设计,当他将学号设置为字符数组时,应该这样设计
    return strcmp(a.id,b.id)<0;
  2. 学生总数不断增加,每个考场的人数起始位等于实时(此时输入完此考场所有学生信息)学生总数减去该考场人数,末位为此时的学生总数;
  3. 这里使用了前面介绍的排名的第二种方法,我之前使用的是第一种方法,显然第二种方法更为简洁。

习题

排序

题目描述
对输入的n个数进行排序并输出。
输入
输入的第一行包括一个整数n(1<=n<=100)。 接下来的一行包括n个整数。
输出
可能有多组测试数据,对于每组数据,将排序后的n个整数输出,每个数后面都有一个空格。
每组测试数据的结果占一行。

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;

int main()
{
	int n;
	int input[110];
	while (scanf("%d", &n)!=EOF)
	{
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &input[i]);
		}
		sort(input, input + n);//这里到底要不要+1?
		for (int i = 0; i < n; i++)
		{
			printf("%d", input[i]);
			if (i != n)
			{
				printf(" ");
			}
		}
		printf("\n");
	}
	return 0;
}

有个问题,

	sort(input, input + n);

这里到底要不要+1?
不能加一!因为可以把input看成input+0,
把后一项看成Input+(n-1)+1
特殊排序

题目描述
输入一系列整数,将其中最大的数挑出,并将剩下的数进行排序。
输入
输入第一行包括1个整数N,1<=N<=1000,代表输入数据的个数。
接下来的一行有N个整数。
输出
可能有多组测试数据,对于每组数据,
第一行输出一个整数,代表N个整数中的最大值,并将此值从数组中去除,将剩下的数进行排序。
第二行将排序的结果输出。

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;

int main()
{
	int n;
	int input[1100];
	while (scanf("%d", &n)!=EOF)
	{
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &input[i]);
		}
		if (n == 1)
		{
			printf("%d\n-1\n", input[0]);
		}
		else 
		{			
			sort(input, input + n);
			printf("%d\n", input[n - 1]);
			input[n - 1] = '\0';
			for (int i = 0; i < n - 1; i++)
			{
				printf("%d", input[i]);
				if (i < n-2)
				{
					printf(" ");
				}
			}
			printf("\n");
		}
	}
	return 0;
}

EXCEL排序

题目描述
Excel可以对一组纪录按任意指定列排序。现请你编写程序实现类似功能。
对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3 时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。
输入
测试输入包含若干测试用例。每个测试用例的第1行包含两个整数 N (N<=100000) 和 C,其中 N 是纪录的条数,C 是指定排序的列号。以下有N行,每行包含一条学生纪录。每条学生纪录由学号(6位数字,同组测试中没有重复的学号)、姓名(不超过8位且不包含空格的字符串)、成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。
输出
对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3 时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;

struct student {
	char id[10];
	char name[10];
	int score;
}stu[100010];

bool cmp1(student a, student b)
{
	return strcmp(a.id, b.id)<0;
}

bool cmp2(student a, student b)
{
	if (!strcmp(a.name, b.name))
		return strcmp(a.id, b.id) < 0;
	else
		return strcmp(a.name, b.name) < 0;
}

bool cmp3(student a, student b)
{
	if (a.score != b.score)
		return a.score<b.score;
	else
		return strcmp(a.id, b.id)<0;
}

int main()
{
	int n,c;
	int nn = 1;
	while (scanf("%d%d", &n, &c), n)
	{
		for (int i = 0; i < n; i++)
		{
			scanf("%s%s%d", stu[i].id, stu[i].name, &stu[i].score);
		}
		switch (c)
		{
		case 1:
		{
			//sort(stu->id, (stu + n)->id);//结构体比较能不能这样偷懒?答:做梦。
			sort(stu, stu + n, cmp1);
			break;
		}
		case 2:
		{
			sort(stu, stu + n, cmp2);
			break;
		}
		case 3:
		{
			sort(stu, stu + n, cmp3);
			break;
		}
		default:
			break;
		}
		printf("Case %d:\n",nn);
		for (int i = 0; i < n; i++)
		{
			printf("%s %s %d\n", stu[i].id, stu[i].name, stu[i].score);
		}
		nn++;
	}
	return 0;
}

case 1:
{
//sort(stu->id, (stu + n)->id);//结构体比较能不能这样偷懒?答:做梦。
sort(stu, stu + n, cmp1);
break;
}

字符串内排序

题目描述
输入一个字符串,长度小于等于200,然后将输出按字符顺序升序排序后的字符串。
输入
测试数据有多组,输入字符串。
输出
对于每组输入,输出处理后的结果。

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
	char str[210];
	int len;
	while (fgets(str, 210, stdin) != NULL)
	{
		len = strlen(str);
		sort(str, str + len-1);
		str[len-1] = '\0';
		puts(str);
	}
	return 0;
}

一直因为格式问题不能AC(题目没有说明清楚),不再纠结这个问题。
Problem B

题目描述
请写一个程序,对于一个m行m列的(1<m<10)的方阵,求其每一行,每一列及主对角线元素之和,最后按照从大到小的顺序依次输出。
输入
共一组数据,输入的第一行为一个正整数,表示m,接下来的m行,每行m个整数表示方阵元素。
输出
从大到小排列的一行整数,每个整数后跟一个空格,最后换行。

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;

bool cmp(int a, int b)
{
	return a > b;
}

int main()
{
	int num[10][10];
	int m;
	int sum[22];
	while (scanf("%d", &m) != EOF)
	{
		int sumi[10] = {}, sumj[10] = {}, sumx[2] = {};
		for (int i = 0; i < m; i++)
		{
			for (int j = 0; j < m; j++)
			{
				scanf("%d", &num[i][j]);
				sumi[i] += num[i][j];
				//if (j == m-1)
				//	getchar();
			}
		}
		for (int j = 0; j < m; j++)
		{
			for (int i = 0; i < m; i++)
				sumj[j] += num[i][j];
		}
		for (int x = 0; x < m; x++)
		{
			sumx[0] += num[x][x];
			sumx[1] += num[x][m - x - 1];
		}
		int p = 0;
		for (int i = 0; i < m; i++)
		{
			sum[p] = sumi[i];
			p++;
		}
		for (int j = 0; j < m; j++)
		{
			sum[p] = sumj[j];
			p++;
		}
		for (int x = 0; x < 2; x++)
		{
			sum[p] = sumx[x];
			p++;
		}
		sort(sum, sum + 2 * m + 2, cmp);
		for (int p = 0; p < 2 * m + 2; p++)
		{
			printf("%d", sum[p]);
			if (p != 2 * m + 1)
				printf(" ");
		}
		printf("\n");
	}
	return 0;
}

小白鼠排队

题目描述
N只小白鼠(1 <= N <= 100),每只鼠头上戴着一顶有颜色的帽子。现在称出每只白鼠的重量,要求按照白鼠重量从大到小的顺序输出它们头上帽子的颜色。帽子的颜色用“red”,“blue”等字符串来表示。不同的小白鼠可以戴相同颜色的帽子。白鼠的重量用整数表示。
输入
多案例输入,每个案例的输入第一行为一个整数N,表示小白鼠的数目。
下面有N行,每行是一只白鼠的信息。第一个为不大于100的正整数,表示白鼠的重量,;第二个为字符串,表示白鼠的帽子颜色,字符串长度不超过10个字符。
注意:白鼠的重量各不相同。
输出
每个案例按照白鼠的重量从大到小的顺序输出白鼠的帽子颜色。

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;

struct mouse {
	int weight;
	char color[15];
}mou[110];

bool cmp(mouse a, mouse b)
{
	return a.weight > b.weight;
}

int main()
{
	int N;

	while (scanf("%d", &N) != EOF)
	{
		for (int i = 0; i < N; i++)
		{
			scanf("%d %s", &mou[i].weight, mou[i].color);//这里可不可以没有空格?
		}
		sort(mou, mou + N, cmp);
		for (int i = 0; i < N; i++)
		{
			printf("%s\n", mou[i].color);
		}
	}
	return 0;
}

for (int i = 0; i < N; i++)
{
scanf("%d %s", &mou[i].weight, mou[i].color);//这里可不可以没有空格?答:可以。
}

中位数

题目描述
中位数定义:一组数据按从小到大的顺序依次排列,处在中间位置的一个数(或最中间两个数据的平均数).
给出一组无序整数,求出中位数,如果求最中间两个数的平均数,向下取整即可(不需要使用浮点数)
输入
该程序包含多组测试数据,每一组测试数据的第一行为N,代表该组测试数据包含的数据个数,1<=N<=10000.
接着N行为N个数据的输入,N=0时结束输入
输出
输出中位数,每一组测试数据输出一行

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;

int main()
{
	int n;
	int	num[10010];
	int temp;
	while (scanf("%d", &n), n)
	{
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &num[i]);
		}
		sort(num, num + n);
		if (n % 2)
			printf("%d\n", num[(n - 1) / 2]);
		else
		{
			temp = (num[n / 2] + num[n / 2 - 1])/2 ;
			printf("%d\n", temp);
		}
	}
}

整数奇偶排序

题目描述
输入10个整数,彼此以空格分隔。重新排序以后输出(也按空格分隔),要求:
1.先输出其中的奇数,并按从大到小排列;
2.然后输出其中的偶数,并按从小到大排列。
输入
任意排序的10个整数(0~100),彼此以空格分隔。
输出
可能有多组测试数据,对于每组数据,按照要求排序后输出,由空格分隔。
提示
多组数据,注意输出格式
1. 测试数据可能有很多组,请使用while(cin>>a[0]>>a[1]>>…>>a[9])类似的做法来实现;
2. 输入数据随机,有可能相等。

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;

bool cmp(int a, int b)
{
	return a > b;
}

int main()
{
	int a[10];//10还是11?
	int a0[10], a1[10];
	while (cin>> a[0] >> a[1] >> a[2] >> a[3] >> a[4] >> a[5] >> a[6] >> a[7] >> a[8] >> a[9])
	{
		int p = 0, q = 0;
		for (int i = 0; i < 10; i++)
		{
			if (a[i] % 2)
			{
				a1[p] = a[i];
				p++;
			}
			else
			{
				a0[q] = a[i];
				q++;
			}
		}
		sort(a1, a1 + p, cmp);
		sort(a0, a0 + q);
		for (int i = 0; i < p; i++)
			printf("%d ", a1[i]);
		for (int i = 0; i < q; i++)
		{
			printf("%d", a0[i]);
			if (i != q - 1)
				printf(" ");
		}
		printf("\n");
	}
	return 0;
}

** 排名**

题目描述
今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的考生,并将他们的成绩按降序打印。
输入
测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N < 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号(题目号由1到M)。
当读入的考生人数为0时,输入结束,该场考试不予处理。
输出
对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考号的升序输出。

#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;

struct student {
	char id[25];
	int n;
	int m[10];
	int score=0;//是不是这样初始化的?
}stu[1010];

bool cmp(student a, student b)
{
	if (a.score == b.score)
		return a.id < b.id;
	else
		return a.score > b.score;
}

int main()
{
	int N, M, G;
	int value[10] = {};
	int sum=0;
	student output[1000];
	while (scanf("%d%d%d", &N, &M, &G), N)
	{
		for (int i = 0; i < M; i++)
		{
			scanf("%d", &value[i]);
		}
		for (int i = 0; i < N; i++)
		{
			scanf("%s%d", stu[i].id,&stu[i].n);
			for (int j = 0; j < stu[i].n; j++)
			{
				scanf("%d", &stu[i].m[j]);
				stu[i].score += value[stu[i].m[j]-1];
			}
		}
		for (int i = 0; i < N; i++)
		{
			if (stu[i].score >= G)
			{
				output[sum] = stu[i];//能不能直接复制?
				sum++;
			}
		}
		sort(output, output + sum, cmp);
		printf("%d\n", sum);
		for (int i = 0; i < sum; i++)
		{
			printf("%s %d\n", output[i].id, output[i].score);
		}
	}
	return 0;
}
发布了43 篇原创文章 · 获赞 4 · 访问量 1219

猜你喜欢

转载自blog.csdn.net/weixin_42176221/article/details/100998916