【题目链接】
ybt 1235:输出前k大的数 OpenJudge 2.4 7617:输出前k大的数
【题目考点】
1. 排序
【君义精讲】排序算法
【解题思路】
要输出前k大的数,需要对数字序列做降序排序。由于数据规模达到
1
0
5
10^5
105,所以必须选用复杂度为
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)的排序方法。 可选的排序方法有归并排序、快速排序、堆排序等。可以选择手写,或使用stl中已有的函数或结构。 由于输入输出数据量较大,建议使用scanf与printf
【题解代码】
解法1:归并排序
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int a[N], t[N], n, k;
void mergeSort(int l, int r)
{
if(l >= r)
return;
int m = (l + r) / 2;
mergeSort(l, m);
mergeSort(m+1,r);
int li = l, ri = m+1, ti = l;
while(li <= m && ri <= r)
{
if(a[li] > a[ri])
t[ti++] = a[li++];
else
t[ti++] = a[ri++];
}
while(li <= m)
t[ti++] = a[li++];
while(ri <= r)
t[ti++] = a[ri++];
for(int i = l; i <= r; ++i)
a[i] = t[i];
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
scanf("%d", &k);
mergeSort(1, n);
for(int i = 1; i <= k; ++i)
printf("%d\n", a[i]);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int a[N], n, k;
bool cmp(int x, int y)
{
return x > y;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
scanf("%d", &k);
stable_sort(a+1, a+1+n, cmp);
for(int i = 1; i <= k; ++i)
printf("%d\n", a[i]);
return 0;
}
解法2:快速排序
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int a[N], n, k;
void quickSort(int l, int r)
{
if(l >= r)
return;
int i = l, j = r;
int mid = a[(l+r)/2];
while(i <= j)
{
while(a[i] > mid)
i++;
while(a[j] < mid)
j--;
if(i <= j)
{
swap(a[i], a[j]);
i++;
j--;
}
}
quickSort(l, j);
quickSort(i, r);
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
scanf("%d", &k);
quickSort(1, n);
for(int i = 1; i <= k; ++i)
printf("%d\n", a[i]);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int a[N], n, k;
bool cmp(int x, int y)
{
return x > y;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
scanf("%d", &k);
sort(a+1, a+1+n, cmp);
for(int i = 1; i <= k; ++i)
printf("%d\n", a[i]);
return 0;
}
解法3:堆排序
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int heap[N], n, k;
bool isPrior(int a, int b)
{
return a > b;
}
void shiftUp(int i)
{
if(i == 1)
return;
if(isPrior(heap[i/2], heap[i]))
{
swap(heap[i], heap[i/2]);
shiftUp(i/2);
}
}
void shiftDown(int i)
{
if(i > n/2)
return;
int sel;
if(2*i+1 <= n && isPrior(heap[2*i],heap[2*i+1]))
sel = 2*i + 1;
else
sel = 2*i;
if(isPrior(heap[i],heap[sel]))
{
swap(heap[sel], heap[i]);
shiftDown(sel);
}
}
void buildHeap()
{
for(int i = n/2; i >= 1; --i)
shiftDown(i);
}
void insert(int val)
{
heap[++n] = val;
shiftUp(n);
}
void del()
{
swap(heap[1], heap[n]);
n--;
shiftDown(1);
}
int top()
{
return heap[1];
}
void heapSort()
{
int tot = n;
for(int i = 1; i <= tot - 1; ++i)
del();
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &heap[i]);
scanf("%d", &k);
buildHeap();
heapSort();
for(int i = 1; i <= k; ++i)
printf("%d\n", heap[i]);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int n, k;
priority_queue<int, vector<int>, less<int> > pq;
int main()
{
int a;
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
{
scanf("%d", &a);
pq.push(a);
}
scanf("%d", &k);
for(int i = 1; i <= k; ++i)
{
printf("%d\n", pq.top());
pq.pop();
}
return 0;
}
|