排序与查找
1.排序
KY210 排序
题目描述
对输入的n个数进行排序并输出。
输入描述:
输入的第一行包括一个整数n(1<=n<=100)。
下来的一行包括n个整数。
输出描述:
可能有多组测试数据,对于每组数据,将排序后的n个整数输出,每个数后面都有一个空格。
每组测试数据的结果占一行。
输入
4
1 4 3 2
输出
1 2 3 4
代码
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int MAXN = 100;
int arr[MAXN];
int main(){
int n;
while (scanf("%d", &n) != EOF){
for(int i = 0; i < n; ++i){
scanf("%d", &arr[i]);
}
sort(arr,arr+n);
for (int i = 0; i < n; ++i) {
printf("%d", arr[i]);
}
printf("\n");
}
return 0;
}
KY9 成绩排序
题目描述
用一维数组存储学号和成绩,然后,按成绩排序输出。
输入描述:
输入第一行包括一个整数N(1<=N<=100),代表学生的个数。
接下来的N行每行包括两个整数p和q,分别代表每个学生的学号和成绩。
输出描述:
按照学生的成绩从小到大进行排序,并将排序后的学生信息打印出来。
如果学生的成绩相同,则按照学号的大小进行从小到大排序。
输入
3
1 90
2 87
3 92
输出
2 87
1 90
3 92
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Student{
int number;
int score;
};
const int MAXN = 100;
Student arr[MAXN];
//按照学号升序和成绩升序的比较函数
bool Compare(Student x, Student y){
if(x.score == y.score){
return x.number < y.number;
} else {
return x.score < y.score;
}
}
int main(){
int n;
scanf("%d",&n);
for(int i = 0; i < n; ++i){
scanf("%d%d", &arr[i].number, &arr[i].score);
}
sort(arr,arr+n,Compare);
for(int i = 0; i < n; ++i){
printf("%d %d\n", arr[i].number, arr[i].score);
}
return 0;
}
KY2 成绩排序
题目描述
查找和排序
题目:输入任意(用户,成绩)序列,可以获得成绩从高到低或从低到高的排列,相同成绩
都按先录入排列在前的规则处理。
示例:
jack 70
peter 96
Tom 70
smith 67
从高到低 成绩
peter 96
jack 70
Tom 70
smith 67
从低到高
smith 67
jack 70
Tom 70
peter 96
输入描述:
输入多行,先输入要排序的人的个数,然后输入排序方法0(降序)或者1(升序)再分别输入他们的名字和成绩,以一个空格隔开。
输出描述:
按照指定方式输出名字和成绩,名字和成绩之间以一个空格隔开
输入
3
0
fang 90
yang 50
ning 70
输出
fang 90
ning 70
yang 50
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Student{
string name;
int score;
int order;
};
bool CompareDescending(Student x, Student y){
if(x.score == y.score){
return x.order < y.order;
}else{
return x.score > y.score;
}
}
bool CompareAscending(Student x, Student y){
if(x.score == y.score){
return x.order < y.order;
}else{
return x.score < y.score;
}
}
int main() {
int n;
int type;
while (scanf("%d%d",&n,&type)!= EOF) {
Student stu[n];
for (int i = 0; i < n; i++) {
cin >> stu[i].name >> stu[i].score;
stu[i].order = i;
}
if (type) {
sort(stu,stu+n,CompareAscending);
}
else {//为0就降序输出
sort(stu,stu+n,CompareDescending);
}
for(int i=0; i < n; ++i){
cout<< stu[i].name<< " " << stu[i].score <<endl;
}
}
return 0;
}
KY211 特殊排序
题目描述
输入一系列整数,将其中最大的数挑出(如果有多个,则挑出一个即可),并将剩下的数进行排序,如果无剩余的数,则输出-1。
输入描述:
输入第一行包括1个整数N,1<=N<=1000,代表输入数据的个数。
接下来的一行有N个整数。
输出描述:
可能有多组测试数据,对于每组数据,
第一行输出一个整数,代表N个整数中的最大值,并将此值从数组中去除,将剩下的数进行排序。
第二行将排序的结果输出。
输入
4
1 3 4 2
输出
4
1 2 3
代码
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 1001;
int arr[MAXN];
int main(){
int n;
while(scanf("%d", &n) != EOF){
int i;
for(int i = 0; i < n; ++i){
scanf("%d", &arr[i]);
}
sort(arr,arr+n);
printf("%d\n", arr[n-1]);
if(n==1){
printf("-1\n");
} else {
for(int i = 0; i < n-2; ++i){
printf("%d ", arr[i]);
}
printf("%d ", arr[n-2]);
}
}
return 0;
}
KY67 整数奇偶排序
题目描述
输入10个整数,彼此以空格分隔。重新排序以后输出(也按空格分隔),要求: 1.先输出其中的奇数,并按从大到小排列; 2.然后输出其中的偶数,并按从小到大排列。
输入描述:
任意排序的10个整数(0~100),彼此以空格分隔。
输出描述:
可能有多组测试数据,对于每组数据,按照要求排序后输出,由空格分隔。
- 测试数据可能有很多组,请使用while(cin>>a[0]>>a[1]>>...>>a[9])类似的做法来实现;
- 输入数据随机,有可能相等。
输入
4 7 3 13 11 12 0 47 34 98
输出
47 13 11 7 3 0 4 12 34 98
代码
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
bool Compare(int x,int y){
return x>y;
}
int main(){
vector<int> a(10);
while(cin>>a[0]>>a[1]>>a[2]>>a[3]>>a[4]>>a[5]>>a[6]>>a[7]>>a[8]>>a[9]){
sort(a.begin(),a.end());
vector<int> odd;
vector<int> even;
for(int i=0;i<10;i++)
if(a[i]%2==0)
even.push_back(a[i]);
else
odd.push_back(a[i]);
sort(even.begin(),even.end());
sort(odd.begin(),odd.end(),Compare);
for(int i=0;i<odd.size();i++){
cout<<odd[i]<<" ";
}
for(int i=0;i<even.size()-1;i++){
cout<<even[i]<<" ";
}
if(even.size()>=1){
cout<<even[even.size()-1]<<endl;
}
}
}
KY37 小白鼠排队
题目描述
N只小白鼠(1 <= N <= 100),每只鼠头上戴着一顶有颜色的帽子。现在称出每只白鼠的重量,要求按照白鼠重量从大到小的顺序输出它们头上帽子的颜色。帽子的颜色用“red”,“blue”等字符串来表示。不同的小白鼠可以戴相同颜色的帽子。白鼠的重量用整数表示。
输入描述:
多案例输入,每个案例的输入第一行为一个整数N,表示小白鼠的数目。
下面有N行,每行是一只白鼠的信息。第一个为不大于100的正整数,表示白鼠的重量,;第二个为字符串,表示白鼠的帽子颜色,字符串长度不超过10个字符。
注意:白鼠的重量各不相同。
输出描述:
每个案例按照白鼠的重量从大到小的顺序输出白鼠的帽子颜色。
输入
3
30 red
50 blue
40 green
输出
blue
green
red
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 100;
struct Mice
{
int weight;
string color;
};
bool Compare(Mice x, Mice y)
{
return x.weight > y.weight;
}
Mice mice[MAXN];
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
for(int i = 0; i < n; ++i)
{
cin >> mice[i].weight >> mice[i].color;
}
sort(mice, mice+n,Compare);
for(int i = 0; i < n; ++i)
{
cout << mice[i].color << endl;
}
}
return 0;
}
KY117 奥运排序问题
题目描述
按要求,给国家进行排名。
输入描述:
有多组数据。
第一行给出国家数N,要求排名的国家数M,国家号从0到N-1。
第二行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。
接下来一行给出M个国家号。
输出描述:
排序有4种方式: 金牌总数 奖牌总数 金牌人口比例 奖牌人口比例
对每个国家给出最佳排名排名方式 和最终排名
格式为: 排名:排名方式
如果有相同的最终排名,则输出排名方式最小的那种排名,对于排名方式,金牌总数 < 奖牌总数 < 金牌人口比例 < 奖牌人口比例
如果有并列排名的情况,即如果出现金牌总数为 100,90,90,80.则排名为1,2,2,4.
每组数据后加一个空行。
输入
4 4
4 8 1
6 6 2
4 8 2
2 12 4
0 1 2 3
4 2
8 10 1
8 11 2
8 12 3
8 13 4
0 3
输出
1:3
1:1
2:1
1:2
1:1
1:1
代码
#include<iostream>
#include<algorithm>
using namespace std;
struct country{
int ID;
int seq;//最终排列的名次
int sortWay;//最优排序的方式
int Seq[4];//1-4不同的排序方式 当前城市的名次
double goldNum;//金牌数
double comNum;//奖牌数
double personNum;//人数
double goldRatio;//金牌比例
double comRatio;//奖牌比例
};
const int MAXN=205;//最多不超过200个国家
const int Max=65535;
bool CompareID(country x,country y)
{
return x.ID < y.ID;
}
bool CompareGoldNum(country x,country y)
{
return x.goldNum > y.goldNum;
}
bool CompareNum(country x,country y)
{
return x.comNum > y.comNum;
}
bool CompareGoldRatio(country x,country y)
{
return x.goldRatio > y.goldRatio;
}
bool CompareComRatio(country x,country y)
{
return x.comRatio > y.comRatio;
}
void sortCountry(country a[],int num)//num代表数组的数量
{
sort(a,a + num,CompareGoldNum); //按金牌数排名
for(int i = 0; i < num; i++)
a[i].Seq[0] = i + 1;
for(int i = 1 ;i < num; i++)
if(a[i].goldNum == a[i-1].goldNum)
a[i].Seq[0] = a[i-1].Seq[0];//考虑并列排名
sort(a, a + num, CompareNum); //按奖牌数排名
for(int i = 0;i < num; i++)
a[i].Seq[1] = i + 1;
for(int i = 1; i < num; i++)
if(a[i].comNum==a[i-1].comNum)
a[i].Seq[1] = a[i-1].Seq[1];//考虑并列排名
sort(a,a+num,CompareGoldRatio); //按金牌人口比排名
for(int i=0;i<num;i++)
a[i].Seq[2]=i+1;
for(int i=1;i<num;i++)
if(a[i].goldRatio==a[i-1].goldRatio)
a[i].Seq[2]=a[i-1].Seq[2];//考虑并列排名
sort(a,a+num,CompareComRatio); //按奖牌人口比排名
for(int i=0;i<num;i++)
a[i].Seq[3]=i+1;
for(int i=1;i<num;i++)
if(a[i].comRatio==a[i-1].comRatio)
a[i].Seq[3]=a[i-1].Seq[3];//考虑并列排名
for(int i=0;i<4;i++)
{
for(int j=0;j<num;j++)
{
if(a[j].seq>a[j].Seq[i])
{
a[j].seq=a[j].Seq[i];
a[j].sortWay=i+1;
}
}
}
sort(a,a+num,CompareID);
for(int i=0;i<num;i++)
cout<<a[i].seq<<":"<<a[i].sortWay<<endl;
}
int main()
{
int n,m;//n指输入的国家数,m指参与排名的国家数(顺位排列)
while(cin>>n>>m)
{
country a[MAXN];
for(int i=0;i<n;i++)
{
cin>>a[i].goldNum>>a[i].comNum>>a[i].personNum;//输入金牌数,奖牌数,人口数
a[i].ID = i;
a[i].goldRatio = 0;a[i].comRatio = 0;//先将平均奖牌数和平均金牌数设置为0
a[i].goldRatio = a[i].goldNum/ a[i].personNum;
a[i].comRatio = a[i].comNum/a[i].personNum;//一般人口不为0,奖牌数可以为0
a[i].seq = Max;//一开始先将排名设置为最大
a[i].sortWay = 0;//一开始的排名方式是0
}
country temp[MAXN];//用来存放需要排名的国家
int Id;
for(int i = 0; i < m; i++)
{
cin>>Id;
temp[i]=a[Id];
}
sortCountry(temp, m);
cout<<endl;
}
return 0;
}
2. 查找
查找涉及的几个基本要素:
- 查找空间:也称解空间,就算在查找空间中寻找符合要求的解的过程。
- 查找目标:需要一个目标来判断查找空间中的各个元素是否符合要求,以便判断查找活得是否成功。
- 查找方法:
- 线性查找
- 二分查找
- 散列查找
KY158 找x
题目描述
输入一个数n,然后输入n个数值各不相同,再输入一个值x,输出这个值在这个数组中的下标(从0开始,若不在数组中则输出-1)。
输入描述:
测试数据有多组,输入n(1<=n<=200),接着输入n个数,然后输入x。
输出描述:
对于每组输入,请输出结果。
输入
2
1 3
0
输出
-1
代码
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 200;
int arr[MAXN];
int main(){
int n;
while(scanf("%d", &n) != EOF){
for(int i = 0; i < n; ++i){
scanf("%d", &arr[i]);
}
int x;
scanf("%d",&x);
int answer = -1;
for(int i = 0; i < n; ++i){
if(arr[i] == x){
answer = i;
break;
}
}
printf("%d\n",answer);
}
return 0;
}
KY199 查找
题目描述
输入数组长度 n 输入数组 a[1...n] 输入查找个数m 输入查找数字b[1...m] 输出 YES or NO 查找有则YES 否则NO 。
输入描述:
输入有多组数据。
每组输入n,然后输入n个整数,再输入m,然后再输入m个整数(1<=m,n<=100)。
输出描述:
如果在n个数组中输出YES否则输出NO。
输入
5
1 5 2 4 3
3
2 5 6
输出
YES
YES
NO
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int const MAXN = 100;
int arr[MAXN];
bool BinarySearch(int n, int target){
int left = 0;
int right = n-1;
while(left <= right){
int middle = (right+left) / 2;
if(arr[middle] < target){
left = middle + 1;
} else if(target < arr[middle]){
right = middle - 1;
} else {
return true;
}
}
return false;
}
int main(){
int n,m;
while(scanf("%d",&n)!=EOF){
for(int i = 0; i < n; ++i){
scanf("%d",&arr[i]);
}
sort(arr,arr + n);
scanf("%d", &m);
for (int i = 0; i < m; ++i) {
int target;
scanf("%d", &target);
if(BinarySearch(n,target)){
printf("YES\n");
}else{
printf("NO\n");
}
}
}
return 0;
}
KY198 找最小数
题目描述
第一行输入一个数n,1 <= n <= 1000,下面输入n行数据,每一行有两个数,分别是x y。输出一组x y,该组数据是所有数据中x最小,且在x相等的情况下y最小的。
输入描述:
输入有多组数据。
每组输入n,然后输入n个整数对。
输出描述:
输出最小的整数对。
输入
5
3 3
2 2
5 5
2 1
3 6
输出
2 1
代码
#include <algorithm>
#include <iostream>
using namespace std;
struct Number{
int x;
int y;
};
const int MAXN = 1001;
Number num[MAXN];
bool Compare(Number a, Number b){
if( a.x == b.x ){
return a.y < b.y;
} else {
return a.x < b.x;
}
};
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
for(int i = 0; i < n; ++i){
cin >> num[i].x >> num[i].y;
}
sort(num, num + n, Compare);
cout << num[0].x << " " << num[0].y << endl;
}
return 0;
}
KY54 打印极值点下标
题目描述
在一个整数数组上,对于下标为i的整数,如果它大于所有它相邻的整数, 或者小于所有它相邻的整数,则称为该整数为一个极值点,极值点的下标就是i。
输入描述:
第一行是此数组的元素个数k(4<k<80),第二行是k个整数,每两个整数之间用空格分隔。
输出描述:
每个案例输出为n行:每行对应于相应数组的所有极值点下标值,下标值之间用空格分隔。
输入
10
10 12 12 11 11 12 23 24 12 12
15
12 12 122 112 222 211 222 221 76 36 31 234 256 76 76
15
12 14 122 112 222 222 222 221 76 36 31 234 256 76 73
输出
0 7
2 3 4 5 6 10 12
0 2 3 10 12 14
代码
#include <stdio.h>
int main(){
int k,i;
int num[80];
while(scanf("%d",&k)!=EOF){
for(i=0;i<k;i++){
scanf("%d",&num[i]);
}
if(num[0]!=num[1])
printf("%d ",0);
for(i=1;i<k-1;i++){
if((num[i]>num[i-1]&&num[i]>num[i+1])||(num[i]<num[i-1]&&num[i]<num[i+1]))
printf("%d ",i);
}
if(num[k-1]!= num[k-2])
printf("%d ",k-1);
printf("\n");
}
return 0;
}
KY228 找位置
题目描述
对给定的一个字符串,找出有重复的字符,并给出其位置,如:abcaaAB12ab12 输出:a,1;a,4;a,5;a,10,b,2;b,11,1,8;1,12, 2,9;2,13。
输入描述:
输入包括一个由字母和数字组成的字符串,其长度不超过100。
输出描述:
可能有多组测试数据,对于每组数据,
按照样例输出的格式将字符出现的位置标出。
1、下标从0开始。
2、相同的字母在一行表示出其出现过的位置。
输入
abcaaAB12ab12
输出
a:0,a:3,a:4,a:9
b:1,b:10
1:7,1:11
2:8,2:12
代码
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main()
{
map<char,vector<int> > st;
vector<int> num,a;
string str;
while(cin>>str){
for(int i = 0; i < str.length(); ++i){
st[str[i]].push_back(i);
if(st[str[i]].size() == 1)
a.push_back(st[str[i]][0]);
}
for(int i = 0; i < a.size(); ++i){
for(auto it = st.begin(); it != st.end(); ++it)
{
num = it->second;
if(str[a[i]] == it->first)
if(num.size() > 1){
for(int j = 0; j < num.size(); j++){
cout<<it->first<<":"<<num[j];
if(j<num.size()-1)cout<<",";
}
cout<<endl;
}
}
}
st.clear();
a.clear();
}
return 0;
}