POJ 2299 超快速排序
两两交换生成有序序列 ----》 数逆序元素的个数 逆序对
mid-i+1 第一个元素的下标 i
子序列之后要有序
在合并的时候数一数逆序对的个数
110 = 6 6/2 = 3 右移一位 011=3 左移动 1100=12
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxn=500010; 6 int a[maxn], b[maxn]; 7 // 不用动态的分配空间 开辟静态数组50个数组或者1w的时间差距并不大,动态数组时间差距比较大。频繁的开辟动态数组会影响算法的效率 8 long long cnt; 9 10 void Merge(int low, int mid, int high){ 11 int i=low, j=mid+1, k=low; 12 while (i<=mid && j<=high) { // 按照从小到大存放到辅助书B[]中 13 if(a[i]<=a[j]) 14 b[k++] = a[i++]; 15 else{ 16 b[k++] = a[j++]; 17 cnt += (long long)(mid-i+1); 18 } 19 } 20 while(i<=mid) b[k++]=a[i++]; 21 while(j<=high) b[k++]=a[j++]; 22 for(k=low; k<=high; k++) 23 a[k] = b[k]; 24 } 25 26 void MergeSort(int low, int high){ 27 if(low<high){ 28 int mid = (low + high) >> 1; //右移操作比除法快 29 // 分数组 30 MergeSort(low, mid); 31 MergeSort(mid+1, high); 32 // 合并 33 Merge(low, mid, high); 34 } 35 } 36 int main(){ 37 int n; 38 while (scanf("%d", &n) && n) { 39 cnt = 0; 40 for(int i=0; i<n; i++) 41 scanf("%d", &a[i]); 42 MergeSort(0, n-1); 43 printf("%lld\n", cnt); // %I64d 杭电不让用lld可以使用%I64d代替 44 } 45 return 0; 46 }
HDU 1031
https://vjudge.net/problem/HDU-1031
对满意度之和排序递减排序(从大到小),满意度相等按id递增(从小到大),取前k个,按照缩影递减输出(从大到小),输出的是索引。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 5 using namespace std; 6 7 struct data{ 8 int id; 9 double value; 10 }a[10010]; 11 12 void Merge(data A[], int low, int mid, int high, bool flag){ // 合并函数 13 data *B= new data[high-low+1]; // 辅助数组 14 int i=low, j=mid+1, k=0; 15 double x, y; 16 // 按照满意度递减、按照索引递减 用flag区别 17 while (i<=mid && j<=high) { 18 19 if(!flag){ 20 x = A[i].value; 21 y = A[j].value; 22 }else{ 23 x = A[i].id; 24 y = A[j].id; 25 } 26 27 if(x>=y) // 保证了id小的在前 28 B[k++] = A[i++]; 29 else 30 B[k++] = A[j++]; 31 } 32 while(i<=mid) B[k++]=A[i++]; 33 while(j<=high) B[k++]=A[j++]; 34 for(i=low, k=0; i<=high; i++, k++) 35 A[i] = B[k]; 36 delete []B; 37 } 38 39 void MergeSort(data A[], int low, int high, bool flag){ 40 if(low < high){ 41 int mid = (low+high)>>1; 42 MergeSort(A, low, mid, flag); 43 MergeSort(A, mid+1, high, flag); 44 Merge(A, low, mid, high, flag); 45 } 46 } 47 48 int main(){ 49 int n, m, k; 50 double x; 51 while (scanf("%d%d%d", &n, &m, &k)!=EOF) { 52 for(int i=0; i<m; i++){ 53 a[i].id = i+1; 54 a[i].value = 0.0; 55 } 56 for(int i=0; i<n; i++){ 57 for(int j=0; j<m; j++){ 58 scanf("%lf", &x); 59 a[j].value += x; 60 } 61 } 62 MergeSort(a, 0, m-1, 0); // 按值非递增 63 MergeSort(a, 0, k-1, 1); // 按序号非递增 我们只要钱前k个 64 for(int i=0; i<k-1; i++) 65 printf("%d ", a[i].id); 66 printf("%d\n", a[k-1].id); 67 } 68 return 0; 69 }
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 5 using namespace std; 6 7 struct data{ 8 int id; 9 double value; 10 }a[10010]; 11 12 bool cmp1(data a, data b){ 13 if(a.value == b.value) 14 return a.id < b.id; 15 return a.value>b.value; 16 } 17 18 bool cmp2(data a, data b){ 19 return a.id > b.id; 20 } 21 22 int main(){ 23 int n, m, k; 24 double x; 25 while (scanf("%d%d%d", &n, &m, &k)!=EOF) { 26 for(int i=0; i<m; i++){ 27 a[i].id = i+1; 28 a[i].value = 0.0; 29 } 30 for(int i=0; i<n; i++){ 31 for(int j=0; j<m; j++){ 32 scanf("%lf", &x); 33 a[j].value += x; 34 } 35 } 36 sort(a, a+m, cmp1); // 按值降序 37 sort(a, a+k, cmp2); // 按序号降序 38 for(int i=0; i<k-1; i++) 39 printf("%d ", a[i].id); 40 printf("%d\n", a[k-1].id); 41 } 42 return 0; 43 }