POJ 2299 Ultra-QuickSort
来源:互联网 发布:淘宝天猫8折代购原理 编辑:程序博客网 时间:2024/06/05 22:30
题目:
Description
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 9 1 0 5 4 ,Ultra-QuickSort produces the output 0 1 4 5 9 .
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Input
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
Output
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
Sample Input
59105431230
Sample Output
60
题意很好理解,输入一个数列,输出它的逆序数。
我的原始代码(超时):
#include<iostream>using namespace std;int n;int c[500005];int num[500005];int sum(int i){int s = 0;while (i){s += c[i];i -= (i&(-i));}return s;}void add(int i, int x){while (i <= n){c[i] += x;i += (i&(-i));}}int findmax(){int max = 1;for (int j = 2; j <= n; j++)if (num[max] < num[j])max = j;return max;}int main(){ios_base::sync_with_stdio(false);long long s;while (cin >> n){if (n == 0)break;for (int i = 1; i <= n; i++){cin >> num[i];c[i] = 0;}s = 0;for (int i = 1; i <= n; i++){int j = findmax();num[j] = -1;s += sum(j);add(j, 1);}cout << s << endl;}return 0;}
很明显它的时间是n*n,所以超时了。
但是好在思路差的不是很多,稍微改了下就对了。
代码:
#include<iostream>#include<algorithm>using namespace std;struct node{int num;int index;};int n;int c[500005];node nod[500005];bool cmp(node a, node b){return a.num > b.num;}int sum(int i){int s = 0;while (i){s += c[i];i -= (i&(-i));}return s;}void add(int i, int x){while (i <= n){c[i] += x;i += (i&(-i));}}int main(){ios_base::sync_with_stdio(false);long long s;while (cin >> n){if (n == 0)break;for (int i = 1; i <= n; i++){cin >> nod[i].num;nod[i].index = i;c[i] = 0;}s = 0;sort(nod + 1, nod + 1 + n, cmp);for (int i = 1; i <= n; i++){int j = nod[i].index;s += sum(j);add(j, 1);}cout << s << endl;}return 0;}
这个虽然过了,但是很慢,我猜想手写快速排序或者归并排序应该会比较快。
普通的归并排序,只需要加一句sum += mid - i + 1;就可以变成边排序边统计逆序数。
代码:
#include<iostream>using namespace std;int n;long long sum;int num[500005];int copynum[500005];void merge(int low, int high){int mid = (low + high) / 2;int i = low, j = mid + 1, k = low;while (i <= mid && j <= high){if (num[i] < num[j])copynum[k++] = num[i++];else{copynum[k++] = num[j++];sum += mid - i + 1;}}while (i <= mid)copynum[k++] = num[i++];while (j <= high)copynum[k++] = num[j++];for (int i = low; i <= high; i++)num[i] = copynum[i];}void sort(int low, int high){if (low == high)return;int mid = (low + high) / 2;sort(low, mid);sort(mid + 1, high);merge(low, high);}int main(){ios_base::sync_with_stdio(false);while (cin >> n){if (n == 0)break;for (int i = 1; i <= n; i++)cin >> num[i];sum = 0;sort(1, n);cout << sum << endl;}return 0;}
2 0
- POJ 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- poj 2299Ultra-quicksort
- POJ-2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 - Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- footable ajax 翻页后没有样式的问题.版本为V2
- smarty总结
- pendingIntent详解
- json的使用
- 【webpack】expose-loader 插件使用
- POJ 2299 Ultra-QuickSort
- 华为oj 删除字符串中出现次数最少的字符
- Entity Framework 6源码学习(一)
- 主人公惺惺著
- OC中data与date
- jQuery datatable 多个查询条件
- 面向对象
- 一个计时器
- iPhone, iPad分辨率