快速排序——HDU 1425

对应HDU 题目:点击打开链接


Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u

[]   [Go Back]   [Status]  

Description

给你n个整数,请按从大到小的顺序输出其中前m大的数。 
 

Input

每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。 
 

Output

对每组测试数据按从大到小的顺序输出前m大的数。 
 

Sample Input

    
    
5 3 3 -35 92 213 -644
 

Sample Output

    
    
213 92 3

Hint

Hint 
请用VC/VC++提交


sort, 归并,快排都能过~快排快点


快排就是,先找序列中的一个数为基数,比如第一个数a[0],使x=a[0]。之后定义i=0, j=n-1(假设数组是0~n-1)。先从后面往前找(即j--)第一个比x小的数a[j],使a[i]=a[j],再从前面往后找(即i++)第一个比x大的数,使a[j]=a[i];再从后面往前找....不断重复,最后当i==j时,使a[i]=x;结束退出。这样做实际是把比x小的都放到x前面,比x大的都放到x后面的一个过程。之后递归操作注意下边界就可以了,如果不熟悉递归,可以画下解答数模拟过程。。。





普通快排:

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
const int MAXN=1000000+10;
using namespace std;
int a[MAXN];

void q_sort(int *A, int l, int r)
{
	if(!(l<r)) return;
	int i=l,j=r;
	int basic=A[l];
	while(i<j)
	{
		while(1)
		{
			if(j==i) break;
			if(A[j]<basic){
				A[i]=A[j]; break;
			}
			j--;
		}
		while(1)
		{
			if(j==i) break;
			if(A[i]>basic){
				A[j]=A[i]; break;
			}
			i++;
		}
	}
	A[i]=basic;
	q_sort(A,l,i-1);
	q_sort(A,i+1,r);
}

int main()
{
	//freopen("in.txt","r",stdin);
	int n,k;
	while(scanf("%d%d", &n,&k)==2)
	{
		for(int i=0; i<n; i++) scanf("%d", &a[i]);
		q_sort(a, 0, n-1);
		//for(int i=0; i<n; i++) cout<<a[i]<<" ";
		//cout<<endl;
		printf("%d", a[n-1]);
		for(int i=n-2; i>=n-k; i--)
			printf(" %d", a[i]);
		printf("\n");
	}
	return 0;
}


随机化快排:


#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<time.h>
#include<cstring>
#include<string>
#include<iostream>
const int MAXN=1000000+10;
using namespace std;
int a[MAXN];

void Swap(int *a, int *b)
{
	if(*a == *b) return;
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

int Get_Rand_Number(int l, int r)  
{     
    static int first_time = 0;  
    if(!first_time){  
        first_time = 1;  
        srand((unsigned int)(time(NULL)));  
    }  
    return rand()%(r - l + 1) + l;  
}  

int GetBase(int *A, int l, int r)
{
	int i, j;
	int t = Get_Rand_Number(l, r);
	Swap(&A[t], &A[r]);
	int base = A[r];
	for(i=l-1, j=l; j<r; j++){
		if(A[j] <= base){
			i++;
			Swap(&A[j], &A[i]);
		}
	}
	Swap(&A[i+1], &A[r]);
	return (i + 1);
}

void q_sort(int *A, int l, int r)
{
	if(l < r){
		int t = GetBase(A, l, r);
		q_sort(A,l,t-1);
		q_sort(A,t+1,r);
	}
}

int main()
{
	//freopen("in.txt","r",stdin);
	int n,k;
	srand((unsigned int)time(0));
	while(scanf("%d%d", &n,&k)==2)
	{
		for(int i=0; i<n; i++) scanf("%d", &a[i]);
		q_sort(a, 0, n-1);
		printf("%d", a[n-1]);
		for(int i=n-2; i>=n-k; i--)
			printf(" %d", a[i]);
		printf("\n");
	}
	return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值