头歌实践平台:数据结构-结构与联合

所有答案直接复制然后把之前的覆盖就好了,觉得有用就点个赞吧!

第1关:工作DDL

任务描述

工作共面临 n(0<n≤1000)个 Deadline(DDL),每个 DDL 有一个完成需要的时间 t 和截止时间 d。如果从 0 时刻开始处理这些 DDL,并且总是选取剩余未处理的 DDL 中截止时间最早的一个去做,如果无法在这个 DDL 的截止时间前完成它,则会战略性放弃这个 DDL,去寻找下一个截止时间最早的 DDL。请设计程序计算:如果从第 0 时刻开始工作,这 n 个 DDL 能完成几个?对于一个完成所需时间为 ti,截止时间为 di 的 DDL,当前时刻为 t,若满足 t+ti<=di,则这个 DDL 可以被完成。

相关知识

参考《C程序设计基础题解与实训指南》。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

输入:第一行一个整数 n(0<n≤1000),之后 n 行每行两个整数 ti 和 di,分别表示第 i 个 DDL 的完成所需时间和截止时间,两个整数都是 int 范围内的正整数。保证每个 DDL 的截止时间不相等。

输出:一个整数 count,为可以完成的 DDL 数。

例如,测试集 1 的输入是: 3 1 2 4 5 3 3 测试集 1 的运行结果为: 2

第一个选择的 DDL 为 "1 2",完成时间为 0+1<=2,符合要求; 第二个选择的 DDL 为 "3 3",完成时间为 1+3>3,不符合要求,不做这个 DDL; 第三个选择的 DDL 为"4 5",完成时间为 1+4<=5,符合要求。 因此答案为 2。


开始你的任务吧,祝你成功!

 #include<stdio.h>
#include<stdlib.h>
struct ddl
{
    int t, d;
} a[1005];
int n, i, t, ans;
/**********Begin**********/
int cmp(const void *a, const void *b)
{
    return (*(struct ddl *)a).d - (*(struct ddl *)b).d;
}
int main()
{
    scanf("%d", &n);
    for (i = 0; i < n; i++)
        scanf("%d%d", &a[i].t, &a[i].d);
    qsort(a, n, sizeof(struct ddl), cmp);
    t = 0;
    ans = 0;
    for (i = 0; i < n; i++)
        if (t + a[i].t <= a[i].d)
        {
            ans++;
            t += a[i].t;
        }
    printf("%d\n", ans);
    return 0;
}
/**********End**********/

第2关:哨兵编号

任务描述

有一排哨兵,请设计程序实现按照身高从大到小将他们编号。哨兵的数量小于 200000 个。

相关知识

参考之前的关卡。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

输入:输入一行,以空格间隔的实数,表示哨兵的身高。

输出:按照输入顺序以 <编号>:<数值> 的格式输出这些数据,要求相同的数值具有相同的编号,各数据之间以空格分隔。数据的数值格式、长度与输入保持不变。

例如测试集 1 的输入是: 5.3 4.7 3.65 12.345 6e2 程序运行结果为: 3:5.3 4:4.7 5:3.65 2:12.345 1:6e2


开始你的任务吧,祝你成功!

#include<stdio.h>
#include<stdlib.h>
struct data_t
{
    double value;
    int order;
    int rank;
    char str[30];
} list[200002];
/**********Begin**********/
int s_rank(const struct data_t * p1, const struct data_t * p2)
{
    if ((p1->value - p2->value) < 0) return 1;
    else return 0;
}
int s_order(const struct data_t * p1, const struct data_t * p2)
{
    return (p1->order - p2->order);
}
void gen_rank(struct data_t data[], int n)
{
    int i;
    data[0].rank = 1;
    for (i = 1; i < n; i++)
        if (data[i].value == data[i - 1].value)
            data[i].rank = data[i - 1].rank;
        else
            data[i].rank = data[i - 1].rank + 1;
}
int main()
{
    int i, n;
    for (n = 0; scanf("%s", list[n].str) != EOF; n++)
    {
        list[n].value = atof(list[n].str);
        list[n].order = n;
    }
    qsort(list, n, sizeof(struct data_t), s_rank);
    gen_rank(list, n);
    qsort(list, n, sizeof(struct data_t), s_order);
    for (i = 0; i < n; i++)
    {
        if (i != 0) putchar(' ');
        printf("%d:%s", list[i].rank, list[i].str);
    }
    return 0;
}
/**********End**********/

第3关:按要求选择钢管

任务描述

从仓库中找出一根钢管,要求: (1)这根钢管一定要是仓库中最长的; (2)这根钢管一定要是最长的钢管中最细的; (3)这根钢管一定要是符合前两条的钢管中编码最大的(每根钢管都有一个互不相同的编码,越大表示生产日期越近)。

手工从几百份钢管材料中选出符合要求的钢管很麻烦,请设计程序解决该问题。

相关知识

参考之前的关卡。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

输入:第一行是一个整数 N(1≤N≤10)表示测试数据的组数,每组测试数据的第一行有一个整数 m(1≤m≤1000),表示仓库中所有钢管的数量,之后 m 行,每行三个整数,分别表示一根钢管的长度(以毫米为单位)、直径(以毫米为单位)和编码(一个 9 位整数)。

输出:每组测试数据只输出一个 9 位整数,表示选出的那根钢管的编码,每个输出占一行。

例如测试集 1 的输入是: 2 2 2000 30 123456789 2000 20 987654321 4 3000 50 872198442 3000 45 752498124 2000 60 765128742 3000 45 652278122 测试集1的运行结果为: 987654321 752498124

 #include<stdio.h>
struct wipe
{
	int len, r, num;
};
int t, n, i;

struct wipe a[1001];
int main()
{
	scanf("%d", &t);
	
	
	while (t--)
	{
		scanf("%d", &n);
	
		int max[3] = {0,0,0}; 
	for(int i = 0;i<n;i++)
    {
		scanf("%d %d %d",&a[i].len,&a[i].r,&a[i].num);		
	}
	
	
	for(int i = 0;i<n;i++)
	{
	
		if(a[i].len>max[0]){
		
		max[2] = a[i].num;
		max[1] = a[i].r;
		max[0] = a[i].len;}
		else
		
		if(a[i].len<max[0]){
		}
	
		else
		
		if(a[i].len==max[0])
		{
			
			if(a[i].r<max[1]){
			
				max[2] = a[i].num;
				max[1] = a[i].r;
				max[0] = a[i].len;}
			else
			
			if(a[i].r>max[1]){
			}
		
			else
			
			if(a[i].r==max[1])
			{
				if(a[i].num>max[2]){
				
					max[2] = a[i].num;
					max[1] = a[i].r;
					max[0] = a[i].len;}
				
			     
				
			}
		}	
			
	}
	printf("%d\n",max[2]);




}
	return 0;
}

第4关:OJ Ratings

任务描述

在很多 OJ(Online Judge) 平台上,rating 被用来衡量用户的水平。现在给出一份某 OJ 的用户名单,你需要找出 rating 最高的用户。给出的用户名单中含有以下三部分内容: nickname: 一个长度在 [1,15] 范围内的字符串,保证字符串中只可能含有大小写字母、数字和下划线,不同用户的 nickname可能重复。 uid: 一个在 [1,107] 范围内的整数,保证不同用户的 uid 不同。 rating: 一个在 [−9999,9999] 范围内的整数,不同用户的 rating 可能重复。 当有多个 rating 最高的用户时,输出 uid 最小的那个用户。

相关知识

参考之前的关卡。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

输入:第一行一个整数 n(1≤n≤105),代表用户个数。接下来的 n 行,每行一个字符串表示 nickname 和两个整数分别表示 uidrating,以空格分隔。

输出:输出一行,一个字符串和两个整数,以空格分隔,表示 rating 最高用户的 nicknameuidrating

例如测试集 1 的输入是: 6 SoaringDream 5455073 233 shorn1 873974 1500 Yukimai 2282197 2161 jqe 1 2161 Dev_XYS 2 1648 RA 3 -8000 测试集1的运行结果为: jqe 1 2161


开始你的任务吧,祝你成功!

#include<stdio.h> 
#include<string.h>
#define M 111111 
typedef struct User User;
struct User {
	int uid, rat;
	char na[20];
};
User u[M];
int n, mx;
int main()
{
	int i;
	scanf("%d", &n);
	for (i = 0; i < n; i++)
	{
		scanf("%s%d%d", u[i].na, &u[i].uid, &u[i].rat);

		/**********Begin**********/
	}
		for(i=0;i<n-1;i++)
		{
			if(u[i].rat>u[i+1].rat)
			{
			u[i+1].rat =  u[i].rat;
		    strcpy(u[i+1].na, u[i].na);
			u[i+1].uid =  u[i].uid ;
			}
			 else
			 
			 if(u[i].rat<u[i+1].rat)
			 {}
			 else
			 if(u[i].rat==u[i+1].rat)
			 {
			 	if(u[i].uid<u[i+1].uid)
				 {
				
			 	u[i+1].rat =  u[i].rat;
				strcpy(u[i+1].na, u[i].na);
				u[i+1].uid =  u[i].uid ;
				}
			 	
				 
			 	
			 }
			mx = n-1;
		}		

	printf("%s %d %d\n", u[mx].na, u[mx].uid, u[mx].rat);
	return 0;
		/**********End**********/
	}

第5关:寻找爱好相同的人

任务描述

每个人有三项爱好,分别是食物,饮料,电影,运动等中的任意三项,第 i 个人的三种爱好分别用一个整数 ai​,bi​,ci​ 来表示。现在给出 n 个人的爱好,如果两个人起码有两项以上的爱好对应的数字相同,那么就认为这两个人具有相同的爱好。请设计程序计算一共有多少对人拥有相同的爱好。满足 ai​==aj​bi​==bj​ci​==cj​ 分别算作一种爱好相同。

相关知识

参考之前的关卡。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

输入:第一行一个整数 n (1≤n≤100),接下来的 n 行,每行三个整数 ai,bi,ci 用空格分割 (0≤ai​,bi​,ci​≤10)。

输出:一个整数,表示拥有相同爱好的人的对数。例如:假如第 1,2,3 人都有相同的爱好,那么有(1,2) (1,3) (2,3) 3 对人有相同的爱好。

例如测试集 1 的输入是: 4 1 2 3 1 2 4 1 2 3 2 2 3 测试集 1 的运行结果为: 5


开始你的任务吧,祝你成功!

 #include<stdio.h>
#define MAXN 100
struct node
{
    int a, b, c;
} p[MAXN + 10];
int main()
{
    int n, i, j, ans = 0;
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
        scanf("%d%d%d", &p[i].a, &p[i].b, &p[i].c);
    /**********Begin**********/
    for (i = 1; i <= n; i++)
        for (j = i + 1; j <= n; j++)
            if ((p[i].a == p[j].a) + (p[i].b == p[j].b) + (p[i].c == p[j].c) >= 2)
                ans++;
    printf("%d\n", ans);
    /**********End**********/
}

第6关:导员的生日推送

任务描述

本关任务:编写一个能计算数组平均值和最大值的小程序。

相关知识

每次班级有同学过生日,班级辅导员就会发一篇公众号,现在请你用程序实现这一需求。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

输入:第一行一个整数 n(n≤50000),表示班级有 n名同学。 随后 n 行,每行有一个字符串 s 和一个字符串 d,中间用空格隔开,其中 s 代表某个同学的相关信息,只含英文字母,长度不超过 50;d 表示这个同学的生日,格式为 xxxx:xx:xx(表示某年某月某日),x 来自字符集 {'0','1','2','3','4','5','6','7','8','9',' '}

输出:多行输出,每行输出包括:一个日期 %d:%d ( 按时间顺序排列) 以及所有该日期过生日同学的相关信息(如果多于一人,按字典序进行排列),用空格隔开。如果该日期没有过生日的同学,就不要输出。

例如测试集 1 的输入是: 3 noname 2000:1:3 a 2000:1:2 b 2000:1:2 测试集1的运行结果为: 1:2 a b 1:3 noname


开始你的任务吧,祝你成功!

#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 
struct infmt {
    char s[51];
    int y, m, d;
} a[50003];
/**********Begin**********/
int cmp(const void *p1, const void *p2)
{
    if (((struct infmt *)p1)->m != ((struct infmt *)p2)->m)
        return ((struct infmt *)p1)->m - ((struct infmt *)p2)->m;
    if (((struct infmt *)p1)->d != ((struct infmt *)p2)->d)
        return ((struct infmt *)p1)->d - ((struct infmt *)p2)->d;
    return strcmp(((struct infmt *)p1)->s, ((struct infmt *)p2)->s);
}
int main()
{
    int n;
    int i;
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
        scanf("%s %d:%d:%d", &a[i].s, &a[i].y, &a[i].m, &a[i].d);
    qsort(a + 1, n, sizeof(a[0]), cmp);
    printf("%d:%d %s", a[1].m, a[1].d, a[1].s);
    for (i = 2; i <= n; i++)
        if (a[i].d != a[i - 1].d || a[i].m != a[i - 1].m)
            printf("\n%d:%d %s", a[i].m, a[i].d, a[i].s);
        else
            printf(" %s", a[i].s);
    return 0;
}
/**********End**********/

第7关:再解约瑟夫问题

任务描述

有 n 个人围成一圈做游戏,1 至 n 编号。从第一个人开始顺序报号 1,2,3。凡报到 3 者退出圈子。最后留在圈子中的人,即为最后的赢家。编号是一开始的编号,整个过程保持不变。

相关知识

参考之前的关卡。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

输入:一个大于 1 的正整数,表示有 n 个人。 输出:输出最后的赢家的编号

例如测试集 1 的输入是: 3 测试集 1 的运行结果为: 2


开始你的任务吧,祝你成功!

 #include<stdio.h>
#include<stdlib.h>
#define Len sizeof(struct number)
struct number        //构建结构体
{
    int num;         //用于计数
    struct number*next;
};
int main()
{
    int n;
    struct number*pt;
    struct number *count(int n);
    scanf("%d", &n);
    pt = count(n);          //引用函数
    printf("%d", pt->num);
    return 0;
}
struct number *count(int n) //返回指针的函数,该指针指向结构体,函数形参为整型
{
    /**********Begin**********/
    struct number*head, *p1, *p2, *tail;
    int i;
    head = p1 = p2 = (struct number*)malloc(Len); //开辟第一个链表
    p2->num = 1;                          //为第一个链表中的元素赋值
    for (i = 2; i < n; i++)
    {
        p1 = (struct number*)malloc(Len); //不断开辟新链表 ,每个链表指向下一个
        p2->next = p1;
        p1->num = i;
        p2 = p1;
    }
    tail = (struct number*)malloc(Len);   //开辟最后一个链表
    p2->next = tail;           //上一个链表指向最后一个链表
    tail->num = n;
    tail->next = head;          //最后一个链表指向头链表
    p1 = head;
    p2 = NULL;              //每隔两个链表删除一个链表
    while (p1 != p2)           //最终会形成一个链表指向自己
    {
        p2 = p1->next;
        p1 = p2->next;
        p2->next = p1->next;
        p1 = p2->next;
    }
    return(p1);              //返回最后剩的链表
    /**********End**********/
}

第8关:数据表排序

任务描述

现代数据库的出现为人们管理各种数据提供了极大的方便,可以说,现在很少有行业背后没有数据库作为支撑。一个典型关系型数据库内部用一张张“表”存储数据,表内的数据代表着现实世界中客观实体的信息,可以说是客观实体的集合。以下是一个“表”的例子:

foodnumbuyDateprice
juice12019-12-2110.209
banana102020-02-02129.98
apple92020-1-1934.55
apple32020-01-1932.2

其中 | food | num | buyDate | price | 可以称为“表头”,里面每一列各不相同的字符串(比如food)作为列名唯一地标识每一列。表头告诉我们这张表将从哪些维度描述客观实体。 之后的每一行称为“元组”,每一个元组对应一个客观实体,每一列中内容的含义和表头所描述的应一致。例如表中的第一个元组: | juice| 1|2019-12-21|10.209|

现在的任务是,为某张表按照一定的关键字顺序排序并输出。为了简化任务,题目将表中的数据类型限制为:

INT:整型数据,同 C 语言中的 int,没有前导 0,排序时按照数字大小排序;

REAL:实数,同C语言中的 double,排序时按照数字大小排序。同时本题中实数的有效数字不会超过 8 位;

VARCHAR:字符串,仅包含大写或小写英文字母,长度不超过 100,排序时按照 C 语言中 strcmp 的规则进行比较;

DATE:日期,格式为 year-month-day,排序时按照日期先后进行排序。输入时保证日期格式一定合法,year 是一个四位数字,但是不保证 month 和 day 一定有两位数字。

按照一定的关键字顺序排序意味着当两个元组的第一关键字值相等的时候,比较第二关键字,以此类推。不会出现所有关键字对应的值都相等的情况。

相关知识

参考之前的关卡。

编程要求

根据提示,在右侧编辑器的Begin-End区域内补充代码。

测试说明

输入: 第一行,两个整数 row 和 col,分别为表的行数(除去表头)和表的列数,列数在 100 及以内,行数在 1000 及以内;

第二行,col 个用一个空格分隔的VARCHAR 类型字符串(列名),代表表头,列名之间保证各不相同;

第三行,col 个用一个空格分隔的字符串,只可能是 INTREALVARCHARDATE,代表每一列中数据的类型;接下来 row 行,每行 col 个用一个空格分隔的数据,每个数据遵循所在列的数据类型的构造规则,每一行代表一个元组。

之后若干行为关键字顺序,每行包括一个列名和一个数字,用一个空格分隔。第 i 行的列名代表第 i 关键字,跟在它后面的数字为 1 或 −1,如果是 1 则该关键字按升序排列,−1 则按降序排列。关键字之间不会重复,此部分行数不会超过列数。

输出:输出排好序的表格,第一行是表头,接下来 row 行是相应的元组。每个数据之间用一个空格分隔。请按原样输出数据。

例如测试集 1 的输入是: 5 5 orderID food num buyDate price INT VARCHAR INT DATE REAL 1 apple 5 2020-1-09 34.55 2 banana 10 2020-01-9 129.98 3 juice 1 2019-12-21 10.209 4 apple 3 2020-01-09 32.2 5 apple 2 2020-1-9 20.1 buyDate 1 food -1 price 1 测试集 1 的运行结果为: orderID food num buyDate price 3 juice 1 2019-12-21 10.209 2 banana 10 2020-01-9 129.98 5 apple 2 2020-1-9 20.1 4 apple 3 2020-01-09 32.2 1 apple 5 2020-1-09 34.55


开始你的任务吧,祝你成功!

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROWNUM 1007
#define COLNUM 107
#define LEN 107
#define INT 0
#define REAL 1
#define VARCHAR 2
#define DATE 3
int type[COLNUM], sp[COLNUM][2], row, col, n;
char title[COLNUM][LEN];
typedef struct table
{
    union attr
    {
        char varchar[LEN];
        double real;
        int date;
        int intNum;
    } A;
    char rawData[LEN];
} T;
T t[ROWNUM][COLNUM];
/**********Begin**********/
void readTable()
{
    int i, j, y, m, d;
    char typeString[LEN];
    scanf("%d %d", &row, &col);
    for (i = 0; i < col; i++)
        scanf("%s", title[i]);
    for (i = 0; i < col; i++)
    {
        scanf("%s", typeString);
        if (strcmp(typeString, "INT") == 0)
            type[i] = INT;
        else if (strcmp(typeString, "REAL") == 0)
            type[i] = REAL;
        else if (strcmp(typeString, "VARCHAR") == 0)
            type[i] = VARCHAR;
        else
            type[i] = DATE;
    }
    for (i = 0; i < row; i++)
        for (j = 0; j < col; j++)
        {
            scanf("%s", t[i][j].rawData);
            switch (type[j])
            {
            case INT:
                sscanf(t[i][j].rawData, "%d", &t[i][j].A.intNum);
                break;
            case REAL:
                sscanf(t[i][j].rawData, "%lf", &t[i][j].A.real);
                break;
            case VARCHAR:
                sscanf(t[i][j].rawData, "%s", t[i][j].A.varchar);
                break;
            case DATE:
                sscanf(t[i][j].rawData, "%d-%d-%d", &y, &m, &d);
                t[i][j].A.date = d + m * 100 + y * 10000;
            default:
                break;
            }
        }
}
void readSP()
{
    int i;
    char colName[LEN];
    while (~scanf("%s %d", colName, &sp[n][1]))
    {
        for (i = 0; i < col; i++)
            if (strcmp(colName, title[i]) == 0)
            {
                sp[n][0] = i;
                break;
            }
        n++;
    }
}
int cmp(const void *a, const void *b)
{
    T *t1 = (T *)a, *t2 = (T *)b;
    int i, c, sgn, ret = 0;
    for (i = 0; i < n; i++)
    {
        c = sp[i][0];
        sgn = sp[i][1];
        switch (type[c])
        {
        case VARCHAR:
            ret = sgn * strcmp(t1[c].A.varchar, t2[c].A.varchar);
            break;
        case INT:
            ret = sgn * (t1[c].A.intNum - t2[c].A.intNum);
            break;
        case REAL:
            if (t1[c].A.real - t2[c].A.real > 0)
                ret = sgn * 1;
            else if (t1[c].A.real - t2[c].A.real < 0)
                ret = sgn * -1;
            else
                ret = 0;
            break;
        case DATE:
            ret = sgn * (t1[c].A.date - t2[c].A.date);
        default:
            break;
        }
        if (ret != 0)
            return ret;
    }
    return 0;
}
void printTable()
{
    int i, j;
    for (j = 0; j < col; j++)
        printf("%s ", title[j]);
    putchar('\n');
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
            printf("%s ", t[i][j].rawData);
        putchar('\n');
    }
}
/**********End**********/
int main()
{
    readTable();
    readSP();
    qsort(t, row, sizeof(*t), cmp);
    printTable();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值