文章目录
- [P1271 【深基9.例1】选举学生会](#P1271 【深基9.例1】选举学生会)
- 选择排序、冒泡排序、插入排序
- 快速排序
- 排序算法的应用
- [[NOIP2006 普及组] 明明的随机数](#[NOIP2006 普及组] 明明的随机数)
- [[NOIP2007 普及组] 奖学金](#[NOIP2007 普及组] 奖学金)
- [P1781 宇宙总统](#P1781 宇宙总统)
排序 计数排序 选择排序 冒泡排序 插入排序 快速排序 排序算法的应用 投票 计数排序的原理与实现 数列排序 明明的随机数 奖学金 宇宙总统 选择排序 冒泡排序 插入排序 快速排序的原理 实现和分析 求第 k 小的数 借助快速排序的思想 使用 STL 中的 sort 进行排序 unique 去重 结构体排序 插入排序与选择排序思想 字符串排序
P1271 【深基9.例1】选举学生会
题目描述
学校正在选举学生会成员,有 n n n( n ≤ 999 n\le 999 n≤999)名候选人,每名候选人编号分别从 1 1 1 到 n n n,现在收集到了 m m m( m ≤ 2000000 m \le 2000000 m≤2000000)张选票,每张选票都写了一个候选人编号。现在想把这些堆积如山的选票按照投票数字从小到大排序。
输入格式
输入 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
cpp
#include<iostream>
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;
}
选择排序、冒泡排序、插入排序
- 选择排序
cpp
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;
}
}
}
- 冒泡排序
cpp
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;
}
}
}
- 插入排序
cpp
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;
}
快速排序
cpp
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) (N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成"去重"与"排序"的工作。
输入格式
输入有两行,第 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 普及组 第一题
cpp
#include<iostream>
#include<algorithm>
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;
}
cpp
#include<iostream>
#include<algorithm>
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 j−1 的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为 1 ∼ n 1\sim n 1∼n(恰好是输入数据的行号减 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
cpp
#include<iostream>
#include<algorithm>
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 1≤n≤20。
cpp
#include<iostream>
#include<algorithm>
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