You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.4 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
int n;
int a[N], b[N];
// 输出原数组
void out() {
for (int i = 1; i <= n; i++) printf("%d ", a[i]);
puts("");
}
// 功能:排序办法
// ①、数小的在前面
// ②、如果数一样大,序号小的在前
bool cmp(int x, int y) {
if (a[x] == a[y]) return x < y;
return a[x] < a[y];
}
// 【方法1】
void func1() {
cin >> n;
// ① 初始化 b[i]=a[i]
// ② 排序(小的在前,大的在后) : a[]
// ③ 每个b[i]通过二分,在排序后的a[]中查找位置记录b[i]=找到的位置
// ④ a[]数组被重新由小到大排序
for (int i = 1; i <= n; i++) cin >> a[i], b[i] = a[i];
// 输出原始数组
out();
// 原始数组由小到大排序
// ① 由小到大排序,不用加什么greater<int>(),代码更简单
// ② 只有由小到大排序后面使用二分进行数值查询位置时才能使用lower_bound二分方法
sort(a + 1, a + n + 1);
// 离散化遍历原始数组b[i],找出它的排名即b[2]=3表示第2个输入的是排名第3的
// 这里的离散化没有用到去重如果需要去重参考788_Unique.cpp
for (int i = 1; i <= n; i++) b[i] = lower_bound(a + 1, a + n + 1, b[i]) - a;
// 倒序,由大到小(视业务调整)
for (int i = n; i; i--) printf("%d ", b[i]);
}
// 【方法2】
void func2() {
cin >> n;
// ① 初始化 b[i]=i
// ② 排序(小的在前,大的在后) : b[]
// ③ a[]数组不动
for (int i = 1; i <= n; i++) cin >> a[i], b[i] = i;
// 输出原始数组
out();
// 对b[]排序
sort(b + 1, b + n + 1, cmp);
// 倒序,由大到小(视业务调整)
for (int i = n; i; i--) printf("%d ", b[i]);
}
/*
10 8 7 9 4
1 4 2 3 5
1a[1]=10
2a[4]=9
3a[2]=8
...
*/
int main() {
// 调用方法1进行测试
freopen("788.in", "r", stdin);
func1();
puts("");
// 在第二次重定向时修改一下cin的状态
cin.clear();
puts("");
// 调用方法2进行测试
freopen("788.in", "r", stdin);
func2();
puts("");
return 0;
}