数据结构之内部排序

目录

7-1 直接插入排序

输入格式:

输出格式:

输入样例:

输出样例:

7-2 寻找大富翁

输入格式:

输出格式:

输入样例:

输出样例:

7-3 PAT排名汇总

输入格式:

输出格式:

输入样例:

输出样例:

7-4 点赞狂魔

输入格式:

输出格式:

输入样例:

输出样例:

7-5 链式基数排序

输入样例:

输出样例:


7-1 直接插入排序

分数 10

全屏浏览题目

切换布局

作者 黄龙军

单位 绍兴文理学院

给定一个整数序列,请按非递减序输出采用直接插入排序的各趟排序后的结果。

输入格式:

测试数据有多组,处理到文件尾。每组测试数据第一行输入一个整数n(1≤n≤100),第二行输入n个整数。

输出格式:

对于每组测试,输出若干行,每行是一趟排序后的结果,每行的每两个数据之间留一个空格。

输入样例:

4
8 7 2 1

输出样例:

7 8 2 1
2 7 8 1
1 2 7 8

 

#include <stdio.h>
#define MaxSize 1000
struct SqList {
    int r[MaxSize + 1];
    int length;
};
void Read(struct SqList *L, int n) {
    L->length = n;
    for (int i = 1; i <= L->length; i++) {
        scanf("%d", &L->r[i]);
    }
}
void Print(struct SqList *L) {
    for (int i = 1; i <= L->length; i++) {
        if (i > 1) printf(" ");
        printf("%d", L->r[i]);
    }
    printf("\n");
}
void InsertSort(struct SqList *L) {
    for (int i = 2; i <= L->length; i++) {
        if (L->r[i] < L->r[i - 1]) {
            L->r[0] = L->r[i];
            int j;
            for (j = i - 1; L->r[0] < L->r[j]; j--)
                L->r[j + 1] = L->r[j];
            L->r[j + 1] = L->r[0];
        }
        Print(L);
    }
}
int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        struct SqList L;
        Read(&L, n);
        InsertSort(&L);
    }
    return 0;
}

 

7-2 寻找大富翁

分数 25

全屏浏览题目

切换布局

作者 陈越

单位 浙江大学

胡润研究院的调查显示,截至2017年底,中国个人资产超过1亿元的高净值人群达15万人。假设给出N个人的个人资产值,请快速找出资产排前M位的大富翁。

输入格式:

输入首先给出两个正整数N(≤106)和M(≤10),其中N为总人数,M为需要找出的大富翁数;接下来一行给出N个人的个人资产值,以百万元为单位,为不超过长整型范围的整数。数字间以空格分隔。

输出格式:

在一行内按非递增顺序输出资产排前M位的大富翁的个人资产值。数字间以空格分隔,但结尾不得有多余空格。

输入样例:

8 3
8 12 7 3 20 9 5 18

输出样例:

20 18 12
#include<stdio.h>
int main(){
    int n,m;
    int a[1000000];
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    int flag=0;
    int t;
    for(int p=n-1;p>=0;p--){
        flag=0;
        for(int i=0;i<p;i++){
            if(a[i]>a[i+1]){
                t=a[i];
                a[i]=a[i+1];
                a[i+1]=t;
                flag=1;
            }
        }
        if(flag==0) break;
    }
    if(m>n){
        for(int i=n-1;i>=1;i--){
            printf("%d ",a[i]);
        }
        printf("%d",a[0]);
    }
    else{
    for(int i=n-1;i>n-m;i--){
        printf("%d ",a[i]);
    }
    printf("%d",a[n-m]);
    }
}

7-3 PAT排名汇总

分数 25

全屏浏览题目

切换布局

作者 陈越

单位 浙江大学

计算机程序设计能力考试(Programming Ability Test,简称PAT)旨在通过统一组织的在线考试及自动评测方法客观地评判考生的算法设计与程序设计实现能力,科学的评价计算机程序设计人才,为企业选拔人才提供参考标准(网址http://www.patest.cn)。

每次考试会在若干个不同的考点同时举行,每个考点用局域网,产生本考点的成绩。考试结束后,各个考点的成绩将即刻汇总成一张总的排名表。

现在就请你写一个程序自动归并各个考点的成绩并生成总排名表。

输入格式:

输入的第一行给出一个正整数N(≤100),代表考点总数。随后给出N个考点的成绩,格式为:首先一行给出正整数K(≤300),代表该考点的考生总数;随后K行,每行给出1个考生的信息,包括考号(由13位整数字组成)和得分(为[0,100]区间内的整数),中间用空格分隔。

输出格式:

首先在第一行里输出考生总数。随后输出汇总的排名表,每个考生的信息占一行,顺序为:考号、最终排名、考点编号、在该考点的排名。其中考点按输入给出的顺序从1到N编号。考生的输出须按最终排名的非递减顺序输出,获得相同分数的考生应有相同名次,并按考号的递增顺序输出。

输入样例:

2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85

输出样例:

9
1234567890005 1 1 1
1234567890014 1 2 1
1234567890001 3 1 2
1234567890003 3 1 2
1234567890004 5 1 4
1234567890012 5 2 2
1234567890002 7 1 5
1234567890013 8 2 3
1234567890011 9 2 4

 

#include <stdio.h>
struct stu
{
    char id[14];                //考号
    int score;                  //分数
    int kc;                     //考场
};
struct stu a[30000];
int bigger(const char *s1,const char *s2)
{
    for(int i=0;i<13;i++)
        if(s1[i] > s2[i])
            return 1;
        else if(s1[i] < s2[i])
        	return 0;
    return 1;
}
void qsort(int l,int r)
{
	if(l >= r)
	return ;
	
    int i = l;
    int j = r;
    struct stu t = a[l];
    while(i != j)
    {
        while(i < j && (a[j].score < t.score || a[j].score == t.score && bigger(a[j].id,t.id)))
            j--;
        while(i < j && (a[i].score > t.score || a[i].score == t.score && bigger(t.id,a[i].id)))
            i++;
        if(i < j)
        {
            struct stu s = a[i];
            a[i] = a[j];
            a[j] = s;
        }
    }
    a[l] = a[i];
    a[i] = t;
    qsort(l,i-1);
    qsort(i+1,r);
    return ;
}
void Copy(int *b2,int *b1,int n)
{
	for(int i=1;i<=n;i++)
	b2[i] = b1[i];
}
int main()
{
    int n,j,i,top = 0;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        int k;
        scanf("%d",&k);
        for(j=0;j<k;j++)
        {
            char id[14];
            int score;
            scanf("%s %d",id,&score);
            a[top].score = score;
            a[top].kc = i;
            strcpy(a[top].id,id);
            top++;
        }
    }
    qsort(0,top-1);
    int levall = 1,b1[n+1],b2[n+1],score = a[0].score;
    for(i=1;i<=n;i++)
        b1[i] = 1,b2[i] = 1;
    printf("%d\n",top);
    printf("%s %d %d %d\n",a[0].id,1,a[0].kc,1);
    int llevall = 1;            //上一个总排名
    levall = 2;                   //总排名
    Copy(b2,b1,n);
    b1[a[0].kc]++;	
    for(i=1;i<top;i++)
    {
        if(a[i].score == a[i-1].score)
        {
            printf("%s %d %d %d\n",a[i].id,llevall,a[i].kc,b2[a[i].kc]);
            levall++;
            b1[a[i].kc]++;
        }
        else
        {
            printf("%s %d %d %d\n",a[i].id,levall,a[i].kc,b1[a[i].kc]);
            llevall = levall;
            levall++;
            
		    Copy(b2,b1,n);
		    b1[a[i].kc]++;					//考场的排名 
        }
    }
    return 0;
}

 

7-4 点赞狂魔

分数 25

全屏浏览题目

切换布局

作者 陈越

单位 浙江大学

微博上有个“点赞”功能,你可以为你喜欢的博文点个赞表示支持。每篇博文都有一些刻画其特性的标签,而你点赞的博文的类型,也间接刻画了你的特性。然而有这么一种人,他们会通过给自己看到的一切内容点赞来狂刷存在感,这种人就被称为“点赞狂魔”。他们点赞的标签非常分散,无法体现出明显的特性。本题就要求你写个程序,通过统计每个人点赞的不同标签的数量,找出前3名点赞狂魔。

输入格式:

输入在第一行给出一个正整数N(≤100),是待统计的用户数。随后N行,每行列出一位用户的点赞标签。格式为“Name K F1​⋯FK​”,其中Name是不超过8个英文小写字母的非空用户名,1≤K≤1000,Fi​(i=1,⋯,K)是特性标签的编号,我们将所有特性标签从 1 到 107 编号。数字间以空格分隔。

输出格式:

统计每个人点赞的不同标签的数量,找出数量最大的前3名,在一行中顺序输出他们的用户名,其间以1个空格分隔,且行末不得有多余空格。如果有并列,则输出标签出现次数平均值最小的那个,题目保证这样的用户没有并列。若不足3人,则用-补齐缺失,例如mike jenny -就表示只有2人。

输入样例:

5
bob 11 101 102 103 104 105 106 107 108 108 107 107
peter 8 1 2 3 4 3 2 5 1
chris 12 1 2 3 4 5 6 7 8 9 1 2 3
john 10 8 7 6 5 4 3 2 1 7 5
jack 9 6 7 8 9 10 11 12 13 14

输出样例:

jack chris john
#include<stdio.h>
typedef struct
{
    char name[20];
    int sum;   //不同标签总数
    int num;    //点赞总数
}User;
int fact[100000000];
int main()
{
    int n,k;
    scanf("%d",&n);
    User users[100];
    int facter[100][1001];
    int i,j;
    for(i=0;i<n;i++)
    {
        users[i].sum=0;
        scanf("%s",users[i].name);
        scanf("%d",&users[i].num);
        for(j=0;j<users[i].num;j++)
        {
            scanf("%d",&facter[i][j]);
            fact[facter[i][j]]++;
            if(fact[facter[i][j]]==1)
                users[i].sum++;
        }
       for(j=0;j<users[i].num;j++) //重新归0
            fact[facter[i][j]]=0;
    }
    //进行排序(这边建议使用选择排序)
    int max;
    for(i=0;i<n-1;i++){
        max=i;
        for(j=i+1;j<n;j++){
            if(users[max].sum<users[j].sum)
                max=j;
            else if(users[max].sum==users[j].sum&&users[max].num>users[j].num)
                max=j;
        }
        User t=users[i];
        users[i]=users[max];
        users[max]=t;
    }
    if(n<3)
    {
        for(i=0;i<n-1;i++)
            printf("%s ",users[i].name);
            printf("%s",users[n-1].name);
        for(i=0;i<3-n;i++)
            printf(" -");
    }
    else
    {
        printf("%s %s %s",users[0].name,users[1].name,users[2].name);
    }
    return 0;
}

7-5 链式基数排序

分数 15

全屏浏览题目

切换布局

作者 王东

单位 贵州师范学院

实现链式基数排序,待排序关键字n满足1≤n≤1000,最大关键字数位≤5。

输入样例:

第一行输入待排序个数n(1≤n≤1000),再输入n个数(n的数位≤5)。

10
278 109 63 930 589 184 505 269 8 83

输出样例:

输出每趟分配-收集后链表中的关键字,趟数为序列中最大值的数位(如样例中930的数位为3),每行结尾有空格。

930 63 83 184 505 278 8 109 589 269 
505 8 109 930 63 269 278 83 184 589 
8 63 83 109 184 269 278 505 589 930 
#include<stdio.h>
struct tong{
    int a[1000];
    int sum;//sum指的是存入桶中的数据个数
};
typedef struct tong tong;
int ad[1000];
int findmax(int n){
    int max=0;
    int t;
    int weishu=0;
    for(int i=0;i<n;i++){
        weishu=0;
        t=ad[i];
        while(t!=0){
            t=t/10;
            weishu++;
        }
        if(weishu>max)
        max=weishu;
    }
    return max;
}
int main(){
    int n;
    int t;
    tong ts[10];
    for(int i=0;i<10;i++)
        ts[i].sum=0;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&ad[i]);
    //接下来我们要找出最大位数
    int wei=findmax(n);
    for(int i=0;i<wei;i++){
        for(int j=0;j<n;j++){
            t=ad[j];
            t=t/pow(10,i);
             t=t%10;
            ts[t].a[ts[t].sum++]=ad[j];
        }
        //接下来取出桶中数据更新ad数组
        int n1=0;
        for(int j=0;j<10;j++){  //10个桶
            for(int k=0;k<ts[j].sum;k++){
                ad[n1++]=ts[j].a[k];
            }
        }
        //打印
        for(int j=0;j<n;j++){
            printf("%d ",ad[j]);
        }
        printf("\n");
        //进行桶的归0
        for(int j=0;j<10;j++){
            //数组没必要更新,反正会覆盖
            ts[j].sum=0;
        }
    }
}

 

  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值