vector与pair的结合使用

前言:

前面我们已经了解了vector和pair的定义与使用,今日我们一起来学习vector与pair的结合使用(以 天梯的 名人堂与代金券 为例)【多余代码均为解释知识点所需】。

vector:数据结构之顺序表进阶——vector

pair:数据结构之结构体进阶——pair

两者结合后的效果:

我们使用pair代替结构体的定义,我们使用vector代替顺序表的定义,我们将两者结合起来,则可以构建出可以容纳两个数据并且有序的结构体。

题目:

对于在中国大学MOOC(http://www.icourse163.org/ )学习“数据结构”课程的学生,想要获得一张合格证书,总评成绩必须达到 60 分及以上,并且有另加福利:总评分在 [G, 100] 区间内者,可以得到 50 元 PAT 代金券;在 [60, G) 区间内者,可以得到 20 元PAT代金券。全国考点通用,一年有效。同时任课老师还会把总评成绩前 K 名的学生列入课程“名人堂”。本题就请你编写程序,帮助老师列出名人堂的学生,并统计一共发出了面值多少元的 PAT 代金券。

输入格式:

输入在第一行给出 3 个整数,分别是 N(不超过 10 000 的正整数,为学生总数)、G(在 (60,100) 区间内的整数,为题面中描述的代金券等级分界线)、K(不超过 100 且不超过 N 的正整数,为进入名人堂的最低名次)。接下来 N 行,每行给出一位学生的账号(长度不超过15位、不带空格的字符串)和总评成绩(区间 [0, 100] 内的整数),其间以空格分隔。题目保证没有重复的账号。

输出格式:

首先在一行中输出发出的 PAT 代金券的总面值。然后按总评成绩非升序输出进入名人堂的学生的名次、账号和成绩,其间以 1 个空格分隔。需要注意的是:成绩相同的学生享有并列的排名,排名并列时,按账号的字母序升序输出。

输入样例:

10 80 5
cy@zju.edu.cn 78
cy@pat-edu.com 87
1001@qq.com 65
uh-oh@163.com 96
test@126.com 39
anyone@qq.com 87
zoe@mit.edu 80
jack@ucla.edu 88
bob@cmu.edu 80
ken@163.com 70

输出样例:

360
1 uh-oh@163.com 96
2 jack@ucla.edu 88
3 anyone@qq.com 87
3 cy@pat-edu.com 87
5 bob@cmu.edu 80
5 zoe@mit.edu 80

代码长度限制                                        16 KB

时间限制                                                250 ms

内存限制                                                64 MB

分析:

本体的数据需要账号(string类型)和分数(int类型),我们完全可以使用pair去定义这个数结构体,我们同时也可以发现其数据具有顺序性,我们可以使用vector去解决。 

代码:

pair与vector输入与访问:

总代码:

#include<iostream>
#include<vector>
using namespace std;
int N, G, K;//定义题目中第一行的量
vector<pair<string, int>> cnt;

//输出输入结果
void out1() {
	cout << "*********************输入结果为************************" << endl;
	for (auto it = cnt.begin(); it != cnt.end(); it++) {
		cout << (*it).first << "  " << (*it).second << endl;
	}
}

int main()
{

	cin >> N >> G >> K;
	//输入初始数据
	for (int i = 0; i < N; i++) {
		string a; int b;
		cin >> a >> b;
		cnt.push_back(make_pair(a, b));
	}
	out1();
	return 0;
}

结果:

分析

构造:
vector<pair<string, int>> cnt;
输入:
for (int i = 0; i < N; i++) {
	string a; int b;
	cin >> a >> b;
	cnt.push_back(make_pair(a, b));
}
访问:

第一种使用真实的地址进行访问:

for (auto it = cnt.begin(); it != cnt.end(); it++) {
	cout << (*it).first << "  " << (*it).second << endl;
}

 使用和数组一样的访问方式:

for (int i = 0;i<N;i++) {
	cout << cnt[i].first << "  " << cnt[i].second << endl;
}

对构造物进行排序:

总代码:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int N, G, K;//定义题目中第一行的量
vector<pair<string, int>> cnt;

//sort排序的规则
bool cmp(pair<string, int> a, pair<string, int> b) {
	if (a.second != b.second)
		return a.second > b.second;
	else
		return a.first < b.first;
}

//输出输入结果
void out1() {
	cout << "*********************输入结果为************************" << endl;
	for (auto it = cnt.begin(); it != cnt.end(); it++) {
		cout << (*it).first << "  " << (*it).second << endl;
	}
}

void out2() {
	cout << "*********************排序后结果************************" << endl;
	for (auto it = cnt.begin(); it != cnt.end(); it++) {
		cout << (*it).first << "  " << (*it).second << endl;
	}
}

int main()
{

	cin >> N >> G >> K;
	//输入初始数据
	for (int i = 0; i < N; i++) {
		string a; int b;
		cin >> a >> b;
		cnt.push_back(make_pair(a, b));
	}
	out1();
	sort(cnt.begin(), cnt.begin() + N, cmp);
	out2();
	return 0;
}
 结果:

分析:

根据题目意思,我们可以知道,首先按照分数优先,账号其次的顺序进行排序

所以排序需要我们自定义,而不是利用已有的函数直接使用:

bool cmp(pair<string, int> a, pair<string, int> b) {
	if (a.second != b.second)
		return a.second > b.second;//如果数据不同,则按照账号的顺序进行排序
	else
		return a.first < b.first;//如果数据相同,则按分数进行排序
}

总:

代码:

最后将我们讲解用的代码,并根据提议修改后所得代码如下:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int N, G, K;//定义题目中第一行的量
int sum = 0;
vector<pair<string, int>> cnt;

//sort排序的规则
bool cmp(pair<string, int> a, pair<string, int> b) {
	if (a.second != b.second)
		return a.second > b.second;
	else
		return a.first < b.first;
}

int main()
{

	cin >> N >> G >> K;
	//输入初始数据
	for (int i = 0; i < N; i++) {
		string a; int b;
		cin >> a >> b;
		if (b >= G) sum += 50;
		else if (b >= 60) sum += 20;
		cnt.push_back(make_pair(a, b));
	}
	sort(cnt.begin(), cnt.begin() + N, cmp);
	cout << sum << endl;
	int pai_ming = 1;//统计排名
	for (int i = 0; i < N; i++) {
		if (pai_ming > K) break;
		cout << pai_ming << " " << cnt[i].first << " " << cnt[i].second << endl;
		if (cnt[i].second == cnt[i + 1].second) continue;//如果相等则不更新 pai_ming ,反之更新
		else pai_ming = i + 2;
	}

	return 0;
}
结果:

总结:

我们可以发现在我们使用了vector和pair结合后我们可以是我们的代码更加的优化。 

上一篇:C语言如何将多维数组名作为函数参数?


下一篇:基于单片机的多种波形发生器设计-三、 软件设计