#include 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(),代码更简单 // ② 只有由小到大排序,后面使用二分进行数值查询位置时,才能使用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 含义: (1)最大的是原始数组的a[1]=10 (2)次大的是原始数组的a[4]=9 (3)三大的是原始数组的a[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; }