算法初步之排序

     这一小节的内容都是排序,排序所能涉及到的内容很多。在这些题目中,冒泡,选择排序偶尔会用到。因为涉及到的数据量并不大,因此不会超时。多数情况下,调用sort函数可以解决大部分需要排序的东西。sort内部采用类似快速排序的的机制运作,很少会超时。还有就是在操作字符串的时候,很多细节还是要注意,否则很容易遇到莫名其妙的运行错误。这一节的题目比较简单,接下来是这一节的九道题目。

 

问题A:

题目描述

对输入的n个数进行排序并输出。

输入

输入的第一行包括一个整数n(1<=n<=100)。 接下来的一行包括n个整数。

输出

可能有多组测试数据,对于每组数据,将排序后的n个整数输出,每个数后面都有一个空格。
每组测试数据的结果占一行。

样例输入

5
5 4 3 1 2

样例输出

1 2 3 4 5 

#include
int main(){
    int n;
    while(scanf("%d",&n)!=-1){
        //只有不到100个数,先试一下选择排序
        //依次从剩下的元素中找到最小(大)的元素
        //设计为先,很重要。根据思路去敲代码,而不是瞎搞,浪费时间
        //流程很重要,remember
        int a[103];
        int i;
        for(i=0;i             scanf("%d",&a[i]);
        }
        for(i=0;i         for(int j=i;j             if(a[j]<=a[i]){
                int temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
        }
        for(i=0;i         printf("%d ",a[i]);
        printf("\n");
    }
    return 0;
}
 

问题B:

题目描述

输入一系列整数,将其中最大的数挑出,并将剩下的数进行排序。

输入

输入第一行包括1个整数N,1<=N<=1000,代表输入数据的个数。

接下来的一行有N个整数。

输出

可能有多组测试数据,对于每组数据,

第一行输出一个整数,代表N个整数中的最大值,并将此值从数组中去除,将剩下的数进行排序。

第二行将排序的结果输出。

样例输入

5
5 3 2 4 1

样例输出

5
1 2 3 4

提示

 

如果数组中只有一个数,当第一行将其输出后,第二行请输出"-1"。

#include
#include

const int M=1005;
int main(){
    //处理只有一个数字的情况:第一行数字,第二行-1
    //处理有N个数字的情况 :第一行最大数,第二行其余数字的升序
    //1~1000
    //数据范围小就是好做
    int n,a[M];
    while(scanf("%d",&n)!=-1){
        if(n==1){
            scanf("%d",&a[0]);
            printf("%d\n",a[0]);
            printf("-1\n");
        }
        else{
            int i;
            for(i=0;i                 scanf("%d",&a[i]);
            }
            for(i=0;i             for(int j=i;j                 if(a[i]>=a[j]){
                    int temp=a[i];
                    a[i]=a[j];
                    a[j]=temp;
                    
                }
            }
            printf("%d\n",a[n-1]);
            for(i=0;i                 printf("%d ",a[i]);
            }
            printf("\n");
        }
        memset(a,0,sizeof(a));
    }
    return 0;
}

 

问题C:

题目描述

Excel可以对一组纪录按任意指定列排序。现请你编写程序实现类似功能。

对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3 时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

输入

测试输入包含若干测试用例。每个测试用例的第1行包含两个整数 N (N<=100000) 和 C,其中 N 是纪录的条数,C 是指定排序的列号。以下有N行,每行包含一条学生纪录。每条学生纪录由学号(6位数字,同组测试中没有重复的学号)、姓名(不超过8位且不包含空格的字符串)、成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。

输出

对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3 时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

样例输入

4 1
000001 Zhao 75
000004 Qian 88
000003 Li 64
000002 Sun 90
4 2
000005 Zhao 95
000011 Zhao 75
000007 Qian 68
000006 Sun 85
4 3
000002 Qian 88
000015 Li 95
000012 Zhao 70
000009 Sun 95
0 3

样例输出

Case 1:
000001 Zhao 75
000002 Sun 90
000003 Li 64
000004 Qian 88
Case 2:
000007 Qian 68
000006 Sun 85
000005 Zhao 95
000011 Zhao 75
Case 3:
000012 Zhao 70
000002 Qian 88
000009 Sun 95
000015 Li 95

#include
#include
#include

const int M=100009;
typedef struct {
    char num[10];
    char name[10];
    int grade;
}students;
students s[M];
bool cmp(students a,students b){
    return strcmp(a.num,b.num)<0;        //remeber this
}                                        //具体实现以后再看
bool cmp1(students a,students b){
    if(!strcmp(a.name,b.name))
    return strcmp(a.num,b.num)<0;
    else
    return strcmp(a.name,b.name)<0;      
}
bool cmp2(students a,students b){
    if(a.grade==b.grade)
    return strcmp(a.num,b.num)<0;
    else
    return a.grade }
int  main(){
    //选择,快速,希尔,桶,奇偶,冒泡,归并
    /*排序有要求
               1:学号递增(冲突时优先)
               2:姓名非递减
               3:分数非递减    */
    /*数据输入,输出格式
            N是记录条数,C是排序选择
            依次6位学号,8位连续姓名,【0,100】的分数
            N位0时程序结束*/
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    int i,n,c,t=0;
    while(scanf("%d%d",&n,&c)!=-1&&n!=0){
            for(i=0;i                 scanf("%s%s%d",s[i].num,s[i].name,&s[i].grade);
            
            }
            switch(c){
                case 1:std::sort(s,s+n,cmp);
                break;
                case 2:std::sort(s,s+n,cmp1);
                break;
                case 3:std::sort(s,s+n,cmp2);
                break;
            }
        t++;
        printf("Case %d:\n",t);
        for(i=0;i         printf("%s %s %d\n",s[i].num,s[i].name,s[i].grade);
        memset(s,0,sizeof(s));
    }
    return 0;
}

 

问题D:

题目描述

输入一个字符串,长度小于等于200,然后将输出按字符顺序升序排序后的字符串。

输入

测试数据有多组,输入字符串。

输出

对于每组输入,输出处理后的结果。

样例输入

tianqin

样例输出

aiinnqt

提示

 

注意输入的字符串中可能有空格。

#include
#include
#include

bool cmp(char a,char b){
    return a }
int  main(){
    //每次都要分析题目后写设计思路
     //输入长度小于200的字符串,对其排序后输出
     //排序选择:字符数组内部排序(考虑空格情况) ,如果不给提示,第一次应该想不到
     //不会,字符串都是些什么玩意儿
     //试一下: 假设全是小写字母,我理解的是输出不含空格
     //这道题简直实在侮辱 ,什么玩意儿
      char a[205],b[205];
      while(gets(a)!=NULL){
          int i,j,l=strlen(a);
          for(i=0,j=0;i               if(a[i])
              b[j++]=a[i];
          }
          int ll=strlen(b);
          std::sort(b,b+ll,cmp);
          printf("%s\n",b);
          memset(b,0,sizeof(b));
      }
    return 0;
}

 

问题E:

题目描述

请写一个程序,对于一个m行m列的(1

输入

共一组数据,输入的第一行为一个正整数,表示m,接下来的m行,每行m个整数表示方阵元素。

输出

从大到小排列的一行整数,每个整数后跟一个空格,最后换行。

样例输入

4
15 8 -2 6
31 24 18 71
-3 -9 27 13
17 21 38 69

样例输出

159 145 144 135 81 60 44 32 28 27

#include
#include
#include

bool cmp(int a,int b){
    return a>b;
}
int  main(){
    //分析:输入m行m列的矩阵(整数,1     //计算行,列,主队角元素之和
    //对计算出的数字排序,需要控制个数m+m+1+1,然后输出
    
    //测试只对一半(在下一次计算时,清空数组)              (什么叫测试数据范围)
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    int m,a[10][10],sum[22];
    while(scanf("%d",&m)!=-1 ){         //忘了写-1而导致输出超限
        memset(a,0,sizeof(a));
        memset(sum,0,sizeof(sum));
    int i,j ;
    for(i=0;i     for(j=0;j         scanf("%d",&a[i][j]);
        sum[i]+=a[i][j];                  //m行数字的和
    }
    for(j=0;j     for(i=0;i         sum[m+j]+=a[i][j];                //m列数字的和
    }
    for(i=0;i     sum[m+m]+=a[i][i];
    sum[m+m+1]+=a[i][m-1-i];
}
    std::sort(sum,sum+m+m+1+1,cmp);
    for(i=0;i     printf("%d ",sum[i]);
    printf("%d\n",sum[m+m+1]);
}
    return 0;
}

 

问题F:

题目描述

 

N只小白鼠(1 <= N <= 100),每只鼠头上戴着一顶有颜色的帽子。现在称出每只白鼠的重量,要求按照白鼠重量从大到小的顺序输出它们头上帽子的颜色。帽子的颜色用“red”,“blue”等字符串来表示。不同的小白鼠可以戴相同颜色的帽子。白鼠的重量用整数表示。

 

输入

 

多案例输入,每个案例的输入第一行为一个整数N,表示小白鼠的数目。

下面有N行,每行是一只白鼠的信息。第一个为不大于100的正整数,表示白鼠的重量,;第二个为字符串,表示白鼠的帽子颜色,字符串长度不超过10个字符。

注意:白鼠的重量各不相同。

 

输出

 

每个案例按照白鼠的重量从大到小的顺序输出白鼠的帽子颜色。

 

样例输入

1
79 omi
9
46 lcg
92 cru
37 ceq
54 vhr
17 wus
27 tnv
13 kyr
95 wld
34 qox

样例输出

omi
wld
cru
vhr
lcg
ceq
qox
tnv
wus
kyr

 

#include
#include
#include

int  main(){
    //N(1~100)个小白鼠,两个值:重量(小等于100)和颜色(十个字符)
    //对重量排序,输出颜色
    //二维数组,排序怎么办?
    //关键点:白鼠的重量各不相同,可以采用那个方法,暂时忘记名字
    //运行奔溃  :char*定义常量字符串,不能改变
    //两个数组:放重量,放颜色,再添加一个数组来排序
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    int n;
    while(scanf("%d",&n)!=-1)  {
        char a[101][10];
        int w[101],t[101];
        memset(a,0,sizeof(a));
        memset(w,0,sizeof(w));
        memset(t,0,sizeof(t));
        int i,j;
        for(i=0;i             scanf("%d",&w[i]);
            scanf("%s",a[w[i]]);
            t[w[i]]=1;
        //    printf("%s",a[w[i]]);
        }
        
        for(j=100;j>=0;j--)
            if(t[j]==1)             //这里会打出多余的换行
        printf("%s\n",a[j]);
    }
    return 0;
}

 

问题G:

题目描述

中位数定义:一组数据按从小到大的顺序依次排列,处在中间位置的一个数(或最中间两个数据的平均数).
给出一组无序整数,求出中位数,如果求最中间两个数的平均数,向下取整即可(不需要使用浮点数)

输入

该程序包含多组测试数据,每一组测试数据的第一行为N,代表该组测试数据包含的数据个数,1<=N<=10000.
接着N行为N个数据的输入,N=0时结束输入

输出

输出中位数,每一组测试数据输出一行

样例输入

1
468
15
501
170
725
479
359
963
465
706
146
282
828
962
492
996
943
0

样例输出

468
501

 

#include
#include
#include
const int M=10003;

//int cmp(const void* a,const void *b){
//    return *(int*)a-*(int*)b;
bool cmp(int a,int b){
    return a }
int  main(){
    //分析:找出中位数(整数,向下取整)
    //输入:N位0时结束(1~10000)
    //排序: 待定
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
     int n,a[M];
     while(scanf("%d",&n)&&n!=0){
         memset(a,0,sizeof(a));
         int i;
         for(i=0;i              scanf("%d",&a[i]);
         }
    //    qsort(a,n,sizeof(int),cmp);        //系统禁止调用这个玩意儿
    std::sort(a,a+n,cmp);                   //调用sort函数不会超时
        if(n%2==1)
        printf("%d\n",a[n/2]);
        else{
            int temp=(a[n/2]+a[(n-1)/2])/2;//自动去掉小数部分
            printf("%d\n",temp);
        }
     }
    return 0;
}

 

问题H:

题目描述

 

输入10个整数,彼此以空格分隔。重新排序以后输出(也按空格分隔),要求:
1.先输出其中的奇数,并按从大到小排列;
2.然后输出其中的偶数,并按从小到大排列。

 

输入

 

任意排序的10个整数(0~100),彼此以空格分隔。

 

输出

 

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

 

样例输入

0 56 19 81 59 48 35 90 83 75 
17 86 71 51 30 1 9 36 14 16 

样例输出

83 81 75 59 35 19 0 48 56 90
71 51 17 9 1 14 16 30 36 86

提示

 


多组数据,注意输出格式

 


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

2. 输入数据随机,有可能相等。

 

#include
#include
#include
#include
using namespace std;

bool cmp1(int a,int b){
    return a>b;
}
bool cmp2(int a,int b){
    return a }
int  main(){
    //输入:十个整数
    //输出:奇数从大到小,偶数从小到大,一行,空格分开
    //这个和之前的数据读入不一样,每次读一组,按照提示的方法写
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    int a[10],odd[10],even[10]; //空间换时间
    while(cin>>a[0]>>a[1]>>a[2]>>a[3]>>a[4]>>a[5]>>a[6]>>a[7]>>a[8]>>a[9]) {     //提示1
         int i,t1=0,t2=0;
         memset(odd,0,sizeof(odd));
         memset(even,0,sizeof(even));
         for(i=0;i<10;i++){
             if(a[i]%2==0)
             even[t2++]=a[i];
             else
             odd[t1++]=a[i];
             
         }
         sort(odd,odd+t1,cmp1);
         sort(even,even+t2,cmp2);
         for(i=0;i          cout<          for(i=0;i          cout<          cout<     }
    return 0;
}

 

问题I:

题目描述

今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的考生,并将他们的成绩按降序打印。

输入

测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N < 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号(题目号由1到M)。 
当读入的考生人数为0时,输入结束,该场考试不予处理。

输出

对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考号的升序输出。

样例输入

3 5 32
17 10 12 9 15
CS22003 5 1 2 3 4 5
CS22004 3 5 1 3
CS22002 2 1 5
0

样例输出

3
CS22003 63
CS22004 44
CS22002 32

提示

 

 


这题比较简单,计算好每个人的分数后按题目要求排序即可。

 

#include
#include
#include
#include
using namespace std;

const int N=1005;
const int M=15;

struct students{
    char admission[20];
    int total;
    int topic[M];
    int sum;
}s[N];
bool cmp(students a,students b){
    if(a.sum==b.sum)
    return strcmp(a.admission,b.admission)<0;
    else
    return a.sum>b.sum;
}
int  main(){
    //输入:人数 N ( 0 < N < 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G
    //第2是第1题至第M题的正整数分值;
    //以下N行,考生的准考证号(长度不超过20的字符串)、解决的题目总数m、以及这m道题的题号(题目号由1到M)。
    //考生人数为0时,输入结束
    //输出: 第1行输出不低于分数线的考生人数n,
    //随后n行按分数从高到低输出上线考生的考号与分数,其间用1空格分隔。
    //若有多名考生分数相同,则按他们考号的升序输出。
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    int n,m,g,i;
    int questions[M];
    while(scanf("%d",&n)&&n!=0) {
        memset(questions,0,sizeof(questions));
        int t=0;
        scanf("%d%d",&m,&g);
        for(i=1;i<=m;i++){
            scanf("%d",&questions[i]);
        }
        for(i=0;i             scanf("%s%d",s[i].admission,&s[i].total);
            for(int j=0;j                 scanf("%d",&s[i].topic[j]);
                s[i].sum+=questions[s[i].topic[j]];
            }
            if(s[i].sum>=g){
                t++;
            }
        }
    std::    sort(s,s+n,cmp);
    printf("%d\n",t);
         for(i=0;i              if(s[i].sum>=g){
                 printf("%s %d\n",s[i].admission,s[i].sum);
             }
             
         }
        
    }
    return 0;
}

 

你可能感兴趣的:(算法初步之排序)