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;
}