排序(洛谷,更新ing)

ACM题集:https://blog.csdn.net/weixin_39778570/article/details/83187443

题目描述
利用快速排序算法将读入的N个数从小到大排序后输出。

P1177 【模板】快速排序
很是伤心,手写的快排和3路快排都T,归并排序取A了....
#include<bits/stdc++.h>
#define fo(i,j,n) for(register int i=j; i<=n; ++i) 
#define ll long long
using namespace std;
int buf[100005];
// 归并排序 
inline void merge(int arr[], int L, int R, int mid){
	int pos = 1;
	int i=L,j=mid+1;
	fo(k,L,R){
		if(j>R || i<=mid&&arr[i]<arr[j]) buf[k]=arr[i++];
		else buf[k]=arr[j++];
	}
	fo(k,L,R){
		arr[k]=buf[k];
	}
}
void mergeSort(int arr[], int L, int R){
	if(L>=R)return;
	int mid = (L+R)>>1;
	mergeSort(arr,L,mid);
	mergeSort(arr,mid+1,R);
	merge(arr,L,R,mid);
}
// 快排 
inline void swap(int &a, int &b){
	int t=a;a=b;b=t;
}
// T
void quickSort(int arr[], int L, int R){
	if(L>=R)return;
	int pos=L,fir=arr[L];
	fo(i,L+1,R){
		if(arr[i]<fir){
			swap(arr[i],arr[++pos]);
		}
	}
	swap(arr[L],arr[pos]);
	quickSort(arr,L,pos-1);
	quickSort(arr,pos+1,R); 
}
int a[100005],n;
// T
void qsort(int L,int R){
	if(L>=R)return;
	int i=L,j=R,k=a[L];
	while(i<j){
		while(i<j&&a[j]>=k)j--;
		swap(a[i],a[j]);
		while(i<j&&a[i]<k)i++;
		swap(a[i],a[j]);
	}
	qsort(L,i-1);
	qsort(i+1,R);
}
// 3路快排,T了两组 
void _3qsort(int L, int R){
	if(L>=R)return;
	int i=L,j=L,fir=a[L];
	fo(k,L+1,R){
		if(a[k]==fir)swap(a[++j],a[k]);
		else if(a[k]<fir)swap(a[i++],a[k]),swap(a[++j],a[k]);
	}
	_3qsort(L,i-1);
	_3qsort(j+1,R);
} 
// 补一个能A的快排
void q_sort(int L, int R){
	int mid = (L+R)>>1;
	int x=a[mid],i=L,j=R;
//	fo(i,L,R)printf("%d%c",a[i],i==R?'\n':' ');
//	cout<<x<<endl;
	while(i<=j){
		while(a[i]<x)i++; // 等号不能加! 遇到局面为中间数最时将会进入无限制的递归。。。如 1 2 1这种
		while(a[j]>x)j--; // 等号不能加!
		if(i<=j)swap(a[i],a[j]),i++,j--;
	}
//	cout<<i<<" "<<j<<endl; 
	if(L<j)q_sort(L,j);
	if(i<R)q_sort(i,R);
}
int main(){
	scanf("%d",&n);
	fo(i,1,n)scanf("%d",&a[i]);
	//quickSort(a,1,n); // T了 
	//mergeSort(a,1,n); // AC,效率和sort差不多 
	//sort(a+1,a+n+1);
	//qsort(1,n);
	_3qsort(1,n);
	fo(i,1,n)printf("%d%c",a[i],i==n?'\n':' ');
	return 0;
}

题目描述
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了NN个11到1000之间的随机整数(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

/*P1059 明明的随机数 排序去重 */
#include<bits/stdc++.h>
#define fo(i,j,n)for(register int i=j; i<=n; ++i)
#define ll long long
using namespace std;
int a[1005],n;
int main(){
	scanf("%d",&n);
	fo(i,1,n)scanf("%d",&a[i]);
	sort(a+1,a+1+n);
	// 去重
	int k=1;
	fo(i,2,n)if(a[i]!=a[i-1]){
		a[++k]=a[i];
	}
	cout<<k<<endl;
	fo(i,1,k)printf("%d%c",a[i],i==k?'\n':' ');
	return 0;
}

题目链接:https://www.luogu.org/problemnew/show/P1068

*P1068 分数线划定 结构体排序 */
#include<bits/stdc++.h>
#define fo(i,j,n)for(register int i=j; i<=n; ++i)
#define ll long long
#define mk make_pair
using namespace std;
vector<pair<int,int>> ver;
bool cmp(const pair<int,int> &a,const pair<int,int> &b){
	if(a.first==b.first)return a.second<b.second;
	else return a>b;
}
int n,m; 
int main(){
	while(scanf("%d%d",&n,&m)==2){
		ver.clear(); 
		int idx,val;
		for(int i=0;i<n;i++){
			scanf("%d%d",&idx,&val);
			ver.push_back(mk(val,idx));
		}	
	
		sort(ver.begin(),ver.end(),cmp);
		int t = floor(1.5*m);	// 取下界
	//	cout<<"t"<<t<<endl;
		int fen = ver[t-1].first;
	//	cout<<"fen"<<fen<<endl;
		int k = t;	
	//	cout<<"k"<<k<<endl;
		fo(i,t,n){
			if(ver[i].first<fen) break;
			k++;
		}
		printf("%d %d\n",fen,k);
		fo(i,0,k-1) printf("%d %d\n",ver[i].second,ver[i].first);
	}	
	return 0;
}

题目链接:https://www.luogu.org/problemnew/show/P1781

/*P1781 宇宙总统 结构体字符串排序,使用了char数组和string两种方式*/
#include<bits/stdc++.h>
#define fo(i,j,n)for(register int i=j; i<=n; ++i)
#define ll long long
#define mk make_pair
using namespace std;

// node一组数据RE 也不知道哪里RE了(后来发现居然是main函数的while(scanf("%d",&n)==1)),这不科学,说好的鲁棒性? 
struct node{
	char s[200];
	int id;
	// 从大到小排序
	bool operator < (const node &a)const{
		int len1=strlen(s);
		int len2=strlen(a.s);
		if(len1>len2)return 1;
		else if(len1<len2) return 0;
		else{
			for(int i=0;i<len1;i++){
				if(s[i]<a.s[i])return 0;
				else if(s[i]>a.s[i]) return 1;
			}
		}
		return 1;
	}
}a[30];
//使用string 
struct Node{
	string s;
	int id;
	int len;
	// 从大到小排序
	bool operator < (const Node&a)const{
		if(len<a.len)return 0;
		else if(len>a.len)return 1;
		else return s>a.s;
	}
}b[30]; 
int n;
int main(){
	scanf("%d",&n);
	fo(i,1,n){
		scanf("%s",a[i].s);
		a[i].id = i;
	//	cin>>b[i].s;
	//	b[i].len=b[i].s.size();
	//	b[i].id=i;
	}
	sort(a+1,a+1+n);
	printf("%d\n%s\n",a[1].id,a[1].s);
//	sort(b+1,b+n+1);
//	printf("%d\n",b[1].id);
//	cout<<b[1].s<<endl;	
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值