sort 练习
练习题
- 题目:浮点数排序
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm> //sort()排序
#include <cmath> //round()来找最近的整数
using namespace std;
const double EPSILON = 1e-6; //两个浮点数的差小于该数则认为两数相等,1 * (10 ^ (-6))
double num[105];
//计算距离它最近的整数的差
double sub(double x)
{
return fabs(x - round(x)); //不知道谁更大,用fabs取绝对值
}
bool cmp(double a, double b)
{
if (fabs(sub(a) - sub(b)) < EPSILON)
{ //差值相等,则用本身的值排序
return a < b;
}
return sub(a) < sub(b);
}
int main()
{
int N;
scanf("%d", &N);
for (int i = 0; i < N; i++)
{
scanf("%lf", &num[i]);
}
sort(num, num + N, cmp);
for (int i = 0; i < N; i++)
{
if (i != (N - 1)) {
//cout << num[i] << " ";
printf("%lf ", num[i]); //%lf默认是保留六位,不需要加.6
}
else {
//cout << num[i] << endl;
printf("%lf\n", num[i]);
}
}
return 0;
}
/*
输入:
9
1.001 2.1 3.2 4.0001 5.00001 6.9 7.2 8.001 9.0
输出:
9.000000 5.000010 4.000100 1.001000 8.001000 2.100000 6.900000 3.200000 7.200000
*/
- 取中位数之后,达到中位数的人可能很多,所以并不是简单的取前一半
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm>
using namespace std;
int score[100005];
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", &score[i]);
}
sort(score, score + n, greater<int>());
printf("%d ", score[(n - 1) / 2]);
int cnt = 0;
for (int i = 0; i < n; i++)
{
if (score[i] >= score[(n - 1) / 2])
cnt++;
else
break;
}
printf("%d\n", cnt);
return 0;
}
/*
输入:
7
76 71 42 4 27 27 20
输出:
27 5
*/
-
交叉排序
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <algorithm> using namespace std; int num[10005]; int main() { int N, l1, l2, r1, r2; scanf("%d%d%d%d%d", &N, &l1, &r1, &l2, &r2); for (int i = 0; i < N; i++) { scanf("%d", &num[i]); } //第l1个下标是l1-1,第r1下标是r1-1 sort(num + l1 - 1, num + r1); sort(num + l2 - 1, num + r2, greater<int>()); for (int i = 0; i < N; i++) { if (i != N - 1) printf("%d ", num[i]); else printf("%d\n", num[i]); } return 0; } /* 输入: 6 1 3 2 4 8 3 1 6 9 2 输出: 1 8 6 3 9 2 */
-
排序之后统计,注意求char数组这种C风格字符串的长度要用strlen(),min虽然只能求两个数中间较小的,但嵌套就能求三个数
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm> //sort, min
#include <cstring> //strlen
using namespace std;
char s[10005];
int main()
{
int len, r = 0 ,g = 0, b = 0;
scanf("%s", s);
len = strlen(s);
sort(s, s + len);
printf("%s\n", s);
for (int i = 0; i < len; i++)
{
if (s[i] == 'R')
r++;
else if (s[i] == 'G')
g++;
else
b++;
}
printf("%d\n", min(min(r, g / 2), b / 3));
return 0;
}
/*
输入:
RGGBBB
输出:
BBBGGR
1
*/
-
计算数据各位之和
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <algorithm> using namespace std; int num[105]; int sumX(int a) { int ans = 0; while (a) { ans += a % 10; a /= 10; } return ans; } bool cmp(int a, int b) { if (sumX(a) == sumX(b)) { return a < b; } return sumX(a) < sumX(b); } int main() { int N; scanf("%d", &N); for (int i = 0; i < N; i++) scanf("%d", &num[i]); sort(num, num + N, cmp); for (int i = 0; i < N; i++) { if (i != N - 1) printf("%d ", num[i]); else printf("%d\n", num[i]); } return 0; } /* 输入: 4 20 12 1 11 输出: 1 11 20 12 */
-
使用结构体
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm>
using namespace std;
/*
输入学生人数和每个学生的分数
输出成绩排名的学生编号
*/
struct Student
{
int score;
int id;
};
bool cmp(Student a, Student b)
{
return a.score > b.score;
}
Student stu[105];
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", &stu[i].score);
stu[i].id = i + 1;
}
sort(stu, stu + n, cmp);
for (int i = 0; i < n; i++)
{
if (i != n - 1)
printf("%d ", stu[i].id);
else
printf("%d\n", stu[i].id);
}
return 0;
}
/*
输入:
5
97
68
51
85
73
输出:
1 4 5 2 3
*/
- 稍微麻烦一些,对于字符串,string定义的话,是不可以用scanf和printf的。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
struct Student
{
//没说学生姓名的长度,所以最好不要用char数组,用string
string name;
//char name[105];
int score[4];
};
Student stu[105];
bool cmp1(Student a, Student b)
{
if (a.score[0] != b.score[0])
return a.score[0] > b.score[0];
return a.name < b.name;
//return strcmp(a.name, b.name) < 0; //小于0,a小;大于0,b小
}
bool cmp2(Student a, Student b)
{
if (a.score[1] != b.score[1])
return a.score[1] > b.score[1];
return a.name < b.name;
}
bool cmp3(Student a, Student b)
{
if (a.score[2] != b.score[2])
return a.score[2] > b.score[2];
return a.name < b.name;
}
bool cmp4(Student a, Student b)
{
if (a.score[3] != b.score[3])
return a.score[3] > b.score[3];
return a.name < b.name;
}
bool cmp(Student a, Student b)
{
int suma = 0, sumb = 0;
for (int i = 0; i < 4; i++)
{
suma += a.score[i];
sumb += b.score[i];
}
if (suma != sumb)
return suma > sumb;
return a.name < b.name;
}
void print()
{
for (int i = 0; i < 3; i++)
{
cout << stu[i].name << " ";
}
cout << stu[3].name << endl;
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
cin >> stu[i].name;
//scanf("%s", stu[i].name); //输入字符数组不需要&
for (int j = 0; j < 4; j++)
scanf("%d", &stu[i].score[j]);
}
sort(stu, stu + n, cmp1);
print();
sort(stu, stu + n, cmp2);
print();
sort(stu, stu + n, cmp3);
print();
sort(stu, stu + n, cmp4);
print();
sort(stu, stu + n, cmp);
print();
return 0;
}
/*
输入:
5
Alice 99 98 97 96
Bob 98 97 96 94
Coy 94 94 95 96
Dan 93 95 96 97
Evan 0 94 95 95
输出:
Alice Bob Coy Dan
Alice Bob Dan Coy
Alice Bob Dan Coy
Dan Alice Coy Evan
Alice Bob Dan Coy
*/
-
抢气球
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Kid
{
int a; //高度
int id;
};
int ans[1005];
Kid k[1005];
int h[1005]; // 气球高度
int used[1005]; // 是否被摘过
bool cmp(Kid x, Kid y)
{
return x.a < y.a;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)
{
scanf("%d", &k[i].a);
k[i].id = i;
}
for (int i = 0; i < m; i++)
{
scanf("%d", &h[i]);
}
sort(k, k + n, cmp);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (!used[j] && h[j] <= k[i].a)
{
ans[k[i].id]++;
used[j] = true;
}
}
}
for (int i = 0; i < n; i++)
{
printf("%d\n", ans[i]);
}
return 0;
}
/*
输入:
10 10
1 2 3 4 5 6 7 8 9 10
3 1 4 6 7 8 9 9 4 12
输出:
1
0
1
2
0
1
1
1
2
0
*/
//时间复杂度:O(nm)
-
将上面的题改为 1 ≤ n , m ≤ 1 0 5 1 \leq n,m \leq 10^5 1≤n,m≤105
机器一秒钟可能运行 1 0 8 10^8 108,所以上面那种不可行
其实每一个孩子并不需要考虑全部的气球,只需要把气球也排序,这样前面的孩子能摘得,后面的孩子就不能摘了。
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <algorithm> using namespace std; struct Children { int a; int id; }; bool cmp(Children x, Children y) { return x.a < y.a; } Children child[100005]; int h[100005]; int ans[100005]; int main() { int n, m, p = 0; //p用来记录上一个孩子摘到哪个了 scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { scanf("%d", &child[i].a); child[i].id = i; } for (int i = 0; i < m; i++) { scanf("%d", &h[i]); } sort(child, child + n, cmp); sort(h, h + m); //为气球排序 for (int i = 0; i < n; i++) { while (p < m && h[p] <= child[i].a) { //摘掉该气球 ans[child[i].id]++; p++; } } for (int i = 0; i < n; i++) { printf("%d\n", ans[i]); } return 0; } //max{O(nlog(n)),O(mlog(m)),O(n+m)}