排序与查找

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),彼此以空格分隔。

输出描述:

可能有多组测试数据,对于每组数据,按照要求排序后输出,由空格分隔。

  1. 测试数据可能有很多组,请使用while(cin>>a[0]>>a[1]>>...>>a[9])类似的做法来实现;
  2. 输入数据随机,有可能相等。

输入

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. 查找

查找涉及的几个基本要素:

  1. 查找空间:也称解空间,就算在查找空间中寻找符合要求的解的过程。
  2. 查找目标:需要一个目标来判断查找空间中的各个元素是否符合要求,以便判断查找活得是否成功。
  3. 查找方法:
    • 线性查找
    • 二分查找
    • 散列查找

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;
}
posted @ 2021-01-31 12:39  张吱吱  阅读(264)  评论(0编辑  收藏  举报