排序算法

文章目录

  • P1271 【深基9.例1】选举学生会
  • 选择排序、冒泡排序、插入排序
  • 快速排序
  • 排序算法的应用
  • [NOIP2006 普及组] 明明的随机数
  • [NOIP2007 普及组] 奖学金
  • P1781 宇宙总统

排序
计数排序
选择排序 冒泡排序 插入排序
快速排序
排序算法的应用
投票
计数排序的原理与实现
数列排序
明明的随机数
奖学金
宇宙总统
选择排序
冒泡排序
插入排序
快速排序的原理 实现和分析
求第 k 小的数 借助快速排序的思想
使用 STL 中的 sort 进行排序 unique 去重
结构体排序 插入排序与选择排序思想
字符串排序

P1271 【深基9.例1】选举学生会

题目描述

学校正在选举学生会成员,有 n n n n ≤ 999 n\le 999 n999)名候选人,每名候选人编号分别从 1 1 1 n n n,现在收集到了 m m m m ≤ 2000000 m \le 2000000 m2000000)张选票,每张选票都写了一个候选人编号。现在想把这些堆积如山的选票按照投票数字从小到大排序。

输入格式

输入 n n n m m m 以及 m m m 个选票上的数字。

输出格式

求出排序后的选票编号。

样例 #1

样例输入 #1

5 10
2 5 2 2 5 2 2 2 1 2

样例输出 #1

1 2 2 2 2 2 2 2 5 5
#include

using namespace std;

int n,m,tmp,a[1010]={0};

signed int main(){
    cin>>n>>m;
    for(int i=0;i<m;i++){
        cin>>tmp;
        a[tmp]++;
    }
    
    for(int i=1;i<=n;i++)
        for(int j=0;j<a[i];j++)
            cout<<i<<" ";
    cout<<endl;
    
    return 0;
}

选择排序、冒泡排序、插入排序

  • 选择排序
for(int i=0;i<n-1;i++){
	for(int j=i+1;j<n;j++){
	if(a[j]<a[i]){
		int p=a[i];
		a[i]=a[j];
		a[j]=p;
		}
	}
}
  • 冒泡排序
for(int i=0;i<n-1;i++){
	for(int j=0;j<n-i-1;j++){
		if(a[j]>a[j+1]){
			int p=a[j];
			a[j]=a[j+1];
			a[j+1]=p;
		}
	}
}
  • 插入排序
for(int i=1;i<n;i++){
	int now=a[i],j;
	for(j=i-1;j>=0;j--)
		if(a[j]>now)
			a[j+1]=a[j]
		else break;
		a[j+1]=now;
}

快速排序

void quick_sort(int a[],int l,int r){
    int i=l,j=r,flag=a[(l+r)/2],tmp;
    do{
        while(a[i]<flag)i++;
        while(a[j]>flag)j--;
        if(i<=j){
            tmp = a[i];
            a[i] = a[j];
            a[j] = tmp;、
            i++;j--;
        }
    }while(i<=j);
    if(l<j)quick_sort(a, l, j);
    if(i<r)quick_sort(a, i, r);
}

排序算法的应用

[NOIP2006 普及组] 明明的随机数

题目描述

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

输入格式

输入有两行,第 1 1 1 行为 1 1 1 个正整数,表示所生成的随机数的个数 N N N

2 2 2 行有 N N N 个用空格隔开的正整数,为所产生的随机数。

** 输出格式**

输出也是两行,第 1 1 1 行为 1 1 1 个正整数 M M M,表示不相同的随机数的个数。

2 2 2 行为 M M M 个用空格隔开的正整数,为从小到大排好序的不相同的随机数。

样例 #1

样例输入 #1

10
20 40 32 67 40 20 89 300 400 15

样例输出 #1

8
15 20 32 40 67 89 300 400

提示

NOIP 2006 普及组 第一题

#include
#include

using namespace std;

const int maxn = 1010;

int a[maxn],ans[maxn],n,cnt=0,tmp=-1;

int main( ){
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i];
    sort(a,a+n);
    for(int i=0;i<n;i++){
        if(a[i]!=tmp)ans[cnt++]=a[i];
        tmp=a[i];
    }
    cout<<cnt<<endl;
    for(int i=0;i<cnt;i++)cout<<ans[i]<<" ";
    return 0;
}

#include
#include

using namespace std;

const int maxn = 1010;

int a[maxn],n,cnt=0;

int main( ){
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i];
    sort(a,a+n);
    cnt = unique(a,a+n)-a;
    cout<<cnt<<endl;
    for(int i=0;i<cnt;i++)cout<<a[i]<<" ";
    return 0;
}

[NOIP2007 普及组] 奖学金

题目描述

某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前 5 5 5 名学生发奖学金。期末,每个学生都有 3 3 3 门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学 排在前面,这样,每个学生的排序是唯一确定的。

任务:先根据输入的 3 3 3 门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前五名名学生的学号和总分。注意,在前 5 5 5 名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分) 是:

7 7 7 279 279 279
5 5 5 279 279 279

这两行数据的含义是:总分最高的两个同学的学号依次是 7 7 7 号、 5 5 5 号。这两名同学的总分都是 279 279 279 (总分等于输入的语文、数学、英语三科成绩之和) ,但学号为 7 7 7 的学生语文成绩更高一些。如果你的前两名的输出数据是:

5 5 5 279 279 279
7 7 7 279 279 279

则按输出错误处理,不能得分。

输入格式

n + 1 n+1 n+1行。

1 1 1 行为一个正整数 n ( ≤ 300 ) n ( \le 300) n(300),表示该校参加评选的学生人数。

2 2 2 n + 1 n+1 n+1 行,每行有 3 3 3 个用空格隔开的数字,每个数字都在 0 0 0 100 100 100 之间。第 j j j 行的 3 3 3 个数字依次表示学号为 j − 1 j-1 j1 的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为 1 ∼ n 1\sim n 1n(恰好是输入数据的行号减 1 1 1)。

所给的数据都是正确的,不必检验。

//感谢 黄小U饮品 修正输入格式

** 输出格式**

5 5 5 行,每行是两个用空格隔开的正整数,依次表示前 5 5 5 名学生的学号和总分。

** 样例 #1**

样例输入 #1

6
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98

样例输出 #1

6 265
4 264
3 258
2 244
1 237

** 样例 #2**

样例输入 #2

8
80 89 89
88 98 78
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98

** 样例输出 #2**

8 265
2 264
6 264
1 258
5 258
#include
#include

using namespace std;

int const MAXN = 310;
int n;

struct student{
    int id,chinese,total;
}a[MAXN];

int cmp(student a,student b){
    if(a.total!=b.total)return a.total>b.total;
    if(a.chinese!=b.chinese)return a.chinese>b.chinese;
    return a.id<b.id;
}

int main(){
    cin>>n;
    for(int i=0;i<n;i++){
        int math,english;
        cin>>a[i].chinese>>math>>english;
        a[i].total = a[i].chinese+math+english;
        a[i].id = i+1;
    }
    sort(a,a+n,cmp);
    for(int i=0;i<5;i++)cout<<a[i].id<<" "<<a[i].total<<endl;
    
    return 0;
}


P1781 宇宙总统

题目描述

地球历公元 6036 年,全宇宙准备竞选一个最贤能的人当总统,共有 n n n 个非凡拔尖的人竞选总统,现在票数已经统计完毕,请你算出谁能够当上总统。

输入格式

第一行为一个整数 n n n,代表竞选总统的人数。

接下来有 n n n 行,分别为第一个候选人到第 n n n 个候选人的票数。

输出格式

共两行,第一行是一个整数 m m m,为当上总统的人的号数。

第二行是当上总统的人的选票。

样例 #1

样例输入 #1

5
98765
12365
87954
1022356
985678

样例输出 #1

4
1022356

** 提示**

票数可能会很大,可能会到 100 100 100 位数字。

1 ≤ n ≤ 20 1 \leq n \leq 20 1n20

#include
#include

using namespace std;
const int MAXN = 25;
struct node{
    string x;
    int num;
}s[MAXN];
bool cmp(node a,node b){
    if(a.x.length()!=b.x.length())return a.x.length()>b.x.length();
    return a.x>b.x;
}
int n;
int main(){
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>s[i].x;
        s[i].num = i+1;
    }
    sort(s,s+n,cmp);
    
    cout<<s[0].num<<endl<<s[0].x;
    
    return 0;
}


  • 练习题
    • 超级书架 2676
    • 车厢重组 1116
    • 欢乐的跳 1152
    • 分数线划定 1068
    • 攀爬者 5143
    • 生日 1104
    • 拼数 1012

你可能感兴趣的:(算法,排序算法,算法,数据结构)