一本通 2.2.1 数据排序

1310:【例2.2】车厢重组

【题目描述】

在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转180度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他退休后,火车站决定将这一工作自动化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。

【题目分析】

#include <bits/stdc++.h>

using namespace std;

int a[10005];
int n;
int main() {
	//input data
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}

	int cnt = 0;
	for (int i = 1; i <= n - 1; i++) {
		for (int j = 1; j <= n - 1; j++) {
			if (a[j] > a[j + 1]) {
				swap(a[j], a[j + 1]);
				cnt++;
			}
		}
	}
	
	cout<<cnt;
	return 0;
}

1311:【例2.5】求逆序对

【题目描述】

给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目。

【题目分析】

#include <bits/stdc++.h>

using namespace std;

int a[100005];
int temp[100005];
int n;
long long cnt = 0;
/*O(n^2)  10000000000 100亿的数据复杂度肯定超时*/
/*将时间复杂度降为O(nlog(n))  50万的数据复杂度不会超时*/
//归并排序的思想
void gcnt(int left, int right) {
	if (left >= right) return;
	int mid = (left + right) / 2;
	gcnt(left, mid);
	gcnt(mid + 1, right);
	int i = left, j = mid + 1;
	int index = left;
	while (i <= mid && j <= right) {
		if (a[i] <= a[j]) temp[index++] = a[i++];
		else {
			temp[index++] = a[j++];
			cnt += mid - i + 1;
		}
	}
	while (i <= mid) temp[index++] = a[i++];
	while (j <= right) temp[index++] = a[j++];
	for (i = left; i <= right; i++)
		a[i] = temp[i];
}



int main() {
	//input data
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	gcnt(1, n);
	cout << cnt;
	return 0;
}

1176:谁考了第k名

【题目描述】

在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第k名学生的学号和成绩。

【题目分析】

#include <bits/stdc++.h>

using namespace std;

struct node {
	int id;
	double score;
} a[105];
bool cmp(node &a, node &b) {
	return a.score >= b.score;
}
int main() {
	//input data
	int n, k;
	cin >> n >> k;
	for (int i = 1; i <= n; i++) {
		cin >> a[i].id >> a[i].score;
	}
	sort(a + 1, a + n + 1, cmp);

	printf("%d %g", a[k].id, a[k].score);

	return 0;
}

1177:奇数单增序列

【题目描述】

给定一个长度为N(不大于500)的正整数序列,请将其中的所有奇数取出,并按升序输出。

【题目分析】

#include <bits/stdc++.h>

using namespace std;


int main() {
	//input data
	int n, a[505];
	int cnt = 0;
	cin>>n;
	for (int i = 1; i <= n; i++) {
		int k;
		cin >> k;
		if (k % 2 == 1) a[++cnt] = k;
	}
	sort(a + 1, a + 1 + cnt);
	cout << a[1];
	for (int i = 2; i <= cnt; i++) {
		cout << "," << a[i];
	}
	return 0;
}

1178:成绩排序

【题目描述】

给出班里某门课程的成绩单,请你按成绩从高到低对成绩单排序输出,如果有相同分数则名字字典序小的在前。

【题目分析】

#include <bits/stdc++.h>

using namespace std;
/*
4
Kitty 80
Hanmeimei 80
Joey 92
Tim 28
*/
struct node {
	char name[20];
	int score;
} info[20];
bool cmp(node &a, node &b) {
	if (a.score > b.score) return true;
	else if (a.score == b.score && strcmp(a.name, b.name) < 0) return true;
	else return false;
}
int main() {
	//input data
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> info[i].name >> info[i].score;
	}
	sort(info + 1, info + n + 1, cmp);
	for (int i = 1; i <= n; i++) {
		cout << info[i].name << " " << info[i].score << endl;
	}
	return 0;
}

1179:奖学金

【题目描述】

某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前55名学生发奖学金。期末,每个学生都有33门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的。

任务:先根据输入的33门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前五名名学生的学号和总分。注意,在前55名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分) 是:

7 279
5 279

这两行数据的含义是:总分最高的两个同学的学号依次是77号、55号。这两名同学的总分都是 279279 (总分等于输入的语文、数学、英语三科成绩之和) ,但学号为7的学生语文成绩更高一些。如果你的前两名的输出数据是:

5 279
7 279

则按输出错误处理,不能得分。

【题目分析】

#include<iostream>
#include<algorithm>

using namespace std;

struct node {
	int id;
	int yuwen;
	int shuxue;
	int yingyu;
	int sum;
} stu[305];

bool cmp(node a, node b) {
	if (a.sum > b.sum) return true;
	if (a.sum == b.sum && a.yuwen > b.yuwen)return true;
	if (a.sum == b.sum && a.yuwen == b.yuwen && a.id < b.id)return true;
	return false;
}

int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		stu[i].id = i;
		cin >> stu[i].yuwen >> stu[i].shuxue >> stu[i].yingyu;
		stu[i].sum = stu[i].yuwen + stu[i].shuxue + stu[i].yingyu;
	}
	sort(stu + 1, stu + n + 1, cmp);
	for (int i = 1; i <= 5; i++) {
		cout << stu[i].id << " " << stu[i].sum << endl;
	}
	return 0;
}

1180:分数线划定

【题目描述】

世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才,A市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根据计划录取人数的150%150%划定,即如果计划录取m名志愿者,则面试分数线为排名第m×150%(向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。

现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。

【题目分析】

#include <bits/stdc++.h>

using namespace std;

struct node {
	int id;
	int score;
} a[5005];
bool cmp(node &x, node &y) {
	if (x.score > y.score) return true;
	else if (x.score == y.score && x.id < y.id) return true;
	else return false;

}
int main() {
	//input data
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i].id >> a[i].score;
	}
	sort(a + 1, a + n + 1, cmp);

	m = floor(m * 1.5);
	int lin = a[m].score;
	int cnt = 0;
	for (int i = 1; i <= n; i++) {
		if (a[i].score < lin) break;
		else
			cnt++;
	}
	cout<<lin<<" "<<cnt<<endl;
	for (int i = 1; i <= n; i++) {
		if (a[i].score < lin) break;
		else
			cout << a[i].id << " " << a[i].score << endl;
	}
	return 0;
}

1181:整数奇偶排序

【题目描述】

给定10个整数的序列,要求对其重新排序。排序要求:

1.奇数在前,偶数在后;

2.奇数按从大到小排序;

3.偶数按从小到大排序。

【题目分析】

#include <bits/stdc++.h>

using namespace std;

int a[15];
bool cmp(int &i, int &j) {
	if (i % 2 == 1 && j % 2 == 0) return true;
	else if (i % 2 == 1 && j % 2 == 1 && i > j) return true;
	else if (i % 2 == 0 && j % 2 == 0 && i < j) return true;
	else  return false;
}
int main() {
	//input data
	int n = 10;
	for (int k = 1; k <= n; k++) {
		cin >> a[k];
	}
	sort(a + 1, a + 1 + n, cmp);

	for (int k = 1; k <= n; k++) {
		cout << a[k] << " ";
	}

	return 0;
}

1182:合影效果

【题目描述】

小云和朋友们去爬香山,为美丽的景色所陶醉,想合影留念。如果他们站成一排,男生全部在左(从拍照者的角度),并按照从矮到高的顺序从左到右排,女生全部在右,并按照从高到矮的顺序从左到右排,请问他们合影的效果是什么样的(所有人的身高都不同)?

【题目分析】

#include <bits/stdc++.h>

using namespace std;
struct node {
	char s[15];
	double h;
} d[45];
bool cmp(node &a, node &b) {
	if (a.s[0] == 'm' && b.s[0] == 'm')
		return a.h < b.h;
	else if (a.s[0] == 'f' && b.s[0] == 'f')
		return a.h > b.h;
	else return a.s[0] == 'm' && b.s[0] == 'f';
}
int main() {
	//input data
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> d[i].s >> d[i].h;
	}
	sort(d + 1, d + 1 + n, cmp);
	for (int i = 1; i <= n; i++) {
		printf("%.2f ", d[i].h);
	}
	return 0;
}

1183:病人排队

【题目描述】

病人登记看病,编写一个程序,将登记的病人按照以下原则排出看病的先后顺序:

1.老年人(年龄 >= 60岁)比非老年人优先看病。

2.老年人按年龄从大到小的顺序看病,年龄相同的按登记的先后顺序排序。

3.非老年人按登记的先后顺序看病。

【题目分析】

#include <bits/stdc++.h>

using namespace std;

struct node {
	char id[15];
	int old;
	int num;
} a[105];
bool cmp(node &m, node &n) {
	if (m.old >= 60 && n.old >= 60) {
		if (m.old > n.old) return true;
		else if (m.old == n.old && m.num < n.num) return true;
		else return false;
	} else if (m.old >= 60 || n.old >= 60) {
		return m.old > n.old;
	} else
		return m.num < n.num;
}
int main() {
	//input data
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i].id >> a[i].old;
		a[i].num = i;
	}
	sort(a + 1, a + 1 + n, cmp);
	for (int i = 1; i <= n; i++) {
		cout << a[i].id << endl;
	}
	return 0;
}

1184:明明的随机数

【题目描述】

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

【题目分析】

#include <bits/stdc++.h>

using namespace std;

int a[1005];
int main() {
	//input data
	int n, cnt = 0;
	cin >> n;
	while (n--) {
		int x;
		cin >> x;
		if (a[x] == 0) cnt++;
		a[x]++;
	}
	cout << cnt << endl;
	for (int i = 1; i <= 1005; i++) {
		if (a[i] != 0) cout << i << " ";
	}
	return 0;
}

1185:单词排序

【题目描述】

输入一行单词序列,相邻单词之间由1个或多个空格间隔,请按照字典序输出这些单词,要求重复的单词只输出一次。(区分大小写)

【题目分析】

#include <bits/stdc++.h>

using namespace std;

string a[105];
int main() {
	//input data
	int i = 1;
	while (cin >> a[i]) i++;
	sort(a + 1, a + i);
	int j = 1;
	while (j < i) {
		cout << a[j] << endl;
		string str = a[j];
		j++;
		while (str.compare(a[j]) == 0) j++;
	}
	return 0;
}

1186:出现次数超过一半的数

【题目描述】

给出一个含有n(0 < n <= 1000)个整数的数组,请找出其中出现次数超过一半的数。数组中的数大于-50且小于50。

【题目分析】

#include <bits/stdc++.h>

using namespace std;

int a[105];
int main() {
	//input data
	int n, x, i;
	cin >> n;
	for (i = 1; i <= n; i++) {
		cin >> x;
		x += 50;
		a[x]++;
		if (a[x] > n / 2) break;
	}
	if (i > n) cout << "no";
	else cout << x - 50;
	return 0;
}

1187:统计字符数

【题目描述】

给定一个由a-z这26个字符组成的字符串,统计其中哪个字符出现的次数最多。

【题目分析】

#include <bits/stdc++.h>

using namespace std;

int a[26];
int main() {
	//input data
	char c;
	while (cin >> c) {
		a[c - 'a']++;
	}
	int maxn = 0, index = 0;
	for (int i = 0; i <= 25; i++) {
		if (maxn < a[i]) {
			maxn = a[i];
			index = i;
		}
	}
	printf("%c %d", index + 'a', maxn);
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值