Lab12-动态分配与结构体(2019.12.16)

Lab12-动态分配与结构体

1. book类型的结构体【简单】

(结构体)101. 结构体和指针的练习,
请定义结构体类型Book包括了书名,价格,出版社等信息。
请定义结构体Book类型的指针,并用malloc函数分配结构体变量的内存空间
【输入】
第1行:一个字符串,表示书名,可能包含空格,长度不大于90个字符。
第2行,一个非负数,表示价格,不超过1000000。
第3行:一个字符串,表示出版社名,可能包含空格,长度不大于30个字符。
【输出】
一行,包含书名,价格,出版社的字符串,格式如下:
name is “书名”, price is $价格, press is “出版社”
价格保留两位小数。
【样例输入】
The C Programming Language, 2nd Edition
63.12
Prentice Hall
【样例输出】
name is “The C Programming Language, 2nd Edition”, price is $63.12, press is “Prentice Hall”

#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct book
    {
        char name[99];
        double price;
        char press[33];
    };
    struct book *p = malloc(sizeof(struct book));
	
    gets(p->name);//指针访问 or gets((*book).name);
    scanf("%lf ",&p->price);
    //或getchar();
    gets(p->press);

    printf("name is \"%s\", price is $%.2lf, press is \"%s\"",p->name,p->price,p->press);
    free(p);
    return 0;
}
2. 赶班车【中等】

(结构体数组)周一至周五,中山北路校区停车场开往闵行校区的校车的发车时间为
6:50、8:30、11:50、13:50、16:50、18:00、20:50
如果今天校车严格按上述时间表发车,告诉你现在的时间,
请问现在离今天的下一班校车发车还有多少分钟?
【输入】
现在的时间,格式为 HH:MM,其中 HH、MM 均为整数,
且满足 0 ≤ HH ≤ 23,00 ≤ MM ≤ 59。
【输出】
一个整数,表示现在离今天的下一班校车发车还有多少分钟。
如果今天已经没有下一班校车,则输出 -1。
如果现在时间刚好为发车时间,则输出 0。
行末无换行。
【样例输入1】
11:40
【样例输出1】
10
【样例输入2】
22:00
【样例输出2】
-1

#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct time
    {
        int hour;
        int min;
    }timetable[7] =
    {{6,50},{8,30},{11,50},{13,50},{16,50},{18,0},{20,50}};

    int h,m;
    scanf("%d:%d",&h,&m);
    if((h>=20 && m>=51) || h>=21){
        printf("-1");
    }
    else if(h<=6 && m<=50){
        printf("%d",(6-h)*60+(50-m));
    }
    else{
        for(int i=0; i<7; i++){
        //timetable[i]是第i个数组结构体,再.hour取的是结构体里的东西
        if(h==timetable[i].hour && m==timetable[i].min){
            printf("0");break;
        }
        if(h>=timetable[i].hour && h<=timetable[i+1].hour){
            printf("%d",timetable[i+1].hour*60+timetable[i+1].min-h*60-m);break;
        }
    }
    }
    return 0;
}
3. tb商品排序【中等】

(我心中的经典题目)
在tb店铺中,商品的信息有:货号、上架日期和售价。
请写一个程序,将商品按照上架日期降序排序;上架日期相同的商品,则按照售价升序排序;上架日期与售价均相同的商品,则按照货号升序排序,货号的排序规则符合字典序。

【Input】
第 1 行:一个整数 T (1≤T≤10) 为问题数。
对于每组测试数据:每组第一行包括一个整数n,(1≤n≤200),接下来的n行,每行表示一个商品信息,具体包括:(1)货号,由两个小写字母和四位数字组成,(2)日期,格式为YYYY-MM-DD, (3)商品售价(最大5位数)。

【Output】
对于每个问题,输出一行问题的编号(0 开始编号,格式:case #0: 等)
接下来的n行,是排序后的 n 个商品的信息,每个商品的信息占一行。

Example:
【input】
3
3
fk0129 2014-01-28 4575
fi9543 2011-12-01 1205
fu6507 2013-03-07 15790
4
al7157 2016-10-28 12678
ox6333 2014-03-16 4629
ip5447 2016-10-28 19332
jf2741 2013-10-21 12264
5
sm6988 2016-09-01 2486
ut8294 2014-10-24 17239
lt8864 2016-09-01 2486
bn4194 2015-12-07 15039
sc1937 2013-04-30 9144
【output】
case #0:
fk0129 2014-01-28 4575
fu6507 2013-03-07 15790
fi9543 2011-12-01 1205
case #1:
al7157 2016-10-28 12678
ip5447 2016-10-28 19332
ox6333 2014-03-16 4629
jf2741 2013-10-21 12264
case #2:
lt8864 2016-09-01 2486
sm6988 2016-09-01 2486
bn4194 2015-12-07 15039
ut8294 2014-10-24 17239
sc1937 2013-04-30 9144

#include <stdio.h>
#include <stdlib.h>
typedef struct
{
    char id[7];
    char date[11];
    int price;
} item;
//itemcmp定义成const的指针是为了提高参数传递的效率;
//itemcmp也可以定义为简单传值的形式:int itemcmp(item item1, item item2);
//根据题意,*p1若排序后相对*p2靠前,则返回小于0,靠后则返回值大于0,相等返回0;
int itemcmp(const item * p1, const item *p2);
//根据题意进行选择排序
void sort(item items[], int n);
int main()
{
    int t, i, j, n;
    scanf("%d ", &t);
    for(i = 0; i < t; i++)
    {
        scanf("%d ", &n);
        item list[n];
        //input
        for(j = 0; j < n; j++)
            scanf("%s %s %d", list[j].id, list[j].date, &list[j].price);

        printf("case #%d:\n", i);
        //排序
        sort(list,n);
        //output
        for(j = 0; j < n; j++)
            printf("%s %s %d\n", list[j].id, list[j].date, list[j].price);
    }
}

//注意,这里些itemcmp有一个技巧(约定):
//根据题意:*p1若排序后相对*p2靠前,则返回值小于0
//根据题意:*p1若排序后相对*p2靠后,则返回值大于0
int itemcmp(const item * p1, const item *p2)
{
    int n = strcmp(p2->date, p1->date);
    if(n!=0)
        return n;
    n = p1->price-p2->price;
    if(n!=0)
        return n;
    n = strcmp(p1->id, p2->id);
    return n;
}
//排序
void sort(item items[], int n)
{
    int j,k,min;
    item temp;
    for(j = 0; j < n; j++)
    {
        min = j;
        for(k = j+1; k<n; k++)
        {
            if(itemcmp(&items[min], &items[k])>0)//返回值大于0,要更新min的位置
                min = k;
        }
        temp = items[j];
        items[j] = items[min];
        items[min] = temp;
    }
}
4. 字符串排序【中等】

(指针)97. 用指向指针的指针方法对输入的n个字符串进行排序。
定义函数Input,Sort,Free。
(1)在Input函数中输入n个字符串并用一个char的数组去指向这些字符串。
(2)每个字符串的存贮空间和char
数组的存贮空间都在free store(heap)中申请。
(3)程序结束前需要在函数Free中释放在free store中申请的空间。
不完全释放就称为内存泄漏(Memory Leak)。

//********** Specification of Input **********
char** Input(int n);
/* PreCondition:
n is the count of strings
PostCondition:
input n strings, and return the address of the char* array
*/

//********** Specification of Free **********
void Free(char**a, int n);
/* PreCondition:
a points to a char* array in free store (heap),
n is a positive integer
PostCondition:
free ALL memory allocated in Input function
*/

//********** Specification of Sort **********
void Sort(char a, int n);
/
PreCondition:
a is pointer which points to an array of char
pointers,
and n is a positive integer
PostCondition:
a is sorted satisfying to the specification
/
int main()
{ char
* p; int n,i; scanf("%d",&n); getchar();
//********** Input is called here **********
p = Input(n);
//******************************************
//********** Sort is called here ***********
Sort(p,n);
//******************************************
for(i=0; i<n; i++) printf("%s\n",p[i]);
Free(p,n);
//******************************************
return 0;
}

【输入】
第1行:一个正整数n
第2至 n+1行,每行一个字符串,可能包含空格,长度不超过30个字符
【输出】
n行,为输入字符串按字典序升序排列
【样例输入】
3
Barack Obama
Vladimir Putin
David William Donald Cameron
【样例输出】
Barack Obama
David William Donald Cameron
Vladimir Putin

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char** Input(int n)
{
    char **p = malloc(sizeof(char *)*n);
    for(int i=0; i<n; i++){
        p[i] = malloc(sizeof(char)*33);
        gets(p[i]);
    }
    return p;
}

void Free(char**a, int n)
{
    for(int i=0; i<n; i++){
        free(a[i]);
    }
    free((a));
}

void Sort(char **a, int n)
{
    int i,j;
    for(i=0; i<n; i++){
        for(j=i+1; j<n; j++){
            if(strcmp(a[i],a[j])>0){
                char *temp;
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;
                //a[i]和a[j]都是指针,可以和temp直接换,不用strcpy
            }
        }
    }
}

int main()
{
    char** p;
    int n,i;
    scanf("%d",&n);
    getchar();
    p = Input(n);
    Sort(p,n);
    for(i=0; i<n; i++)
        printf("%s\n",p[i]);
    Free(p,n);
   return 0;
}
5. 统计考分【困难】

(循环,数组)
N名考生参加一场考试。这场考试共有M道题,每道题目分值不一,考生答对题目的总分达到或超过G则算通过考试。
告诉你每道题的分值,以及每名考生答对的题目的编号,
请按照总成绩降序的顺序,输出通过考试的考生号和分数。
【输入】
第1行有3个正整数,分别为参加考试的人数 N (1 ≤ N ≤ 10)、问题数M (1 ≤ M ≤ 10)、通过分数线G;
第2行有空格分隔的 M 个正整数,分别为第1题至第 M 题的分值
随后 N 行,每行给出一名考生的考生号、答对问题数量s、
以及这s道题的题号(问题从1开始编号),两两之间以一个空格隔开。
输入数据保证所有输入和输出整数在 int 范围内,考生号为长度不超过20的无空格字符串且不重复。
【输出】
第1行输出一个整数X,表示通过考试的考生数量,
接下来的X行,按总分降序输出通过考试的每位考生的考生号与总分,用空格隔开。
如果有考生的答对题目的总分相等,则考生号字符串的字典序较小的排在前面。
【样例输入】
4 5 25
10 10 12 13 15
SE004 3 5 1 3
SE003 5 2 4 1 3 5
SE002 2 1 2
SE001 3 2 3 5
【样例输出】
3
SE003 60
SE001 37
SE004 37

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct inf
{
    char stuNo[51];
    int amount;
    int qNo[11];
    int score;
};

void Sort(struct inf *a, int n)
{
    int i,j,first;
    struct inf temp;
    for(i=0; i<n-1; i++)
    {
        first = i;
        for(j=i+1; j<n; j++)
        {
            if(stucmp(&a[first], &a[j]) > 0)
            {
                first = j;
            }
        }
        temp = a[i];
        a[i] = a[first];
        a[first] = temp;
    }
}

int stucmp(struct inf *p1, struct inf *p2)
{
    int n = p1->score - p2->score;
    if(n < 0)
        return 1;
    if(n > 0)
        return -1;
    if(strcmp(p1->stuNo, p2->stuNo) > 0)
        return 1;
    if(strcmp(p1->stuNo, p2->stuNo) < 0)
        return -1;
    return 0;
}

int main()
{
    int N,M,G;
    int i,j;
    scanf("%d %d %d",&N,&M,&G);
    //每道题的分值
    int standard[M];
    for(i=0; i<M; i++)
    {
        scanf("%d",&standard[i]);
    }
    struct inf stu[N];
    //输入学生信息
    for(i=0; i<N; i++)
    {
        scanf("%s",stu[i].stuNo);
        scanf("%d",&stu[i].amount);
        for(j=0; j<stu[i].amount; j++)
            scanf("%d",&stu[i].qNo[j]);
    }
    //计算分数
    for(i=0; i<N; i++)
    {
        j=0;
        stu[i].score = 0;
        while(j != stu[i].amount)
        {
            int s = stu[i].qNo[j]-1;
            stu[i].score += standard[s];
            j++;
        }
    }
    Sort(stu, N);
    //统计合格人数
    int cnt=0;
    for(i=0; i<N; i++)
    {
        if(stu[i].score>=G)
        {
            cnt++;
        }
    }
    printf("%d\n",cnt);
    for(i=0; i<cnt; i++)
    {
        printf("%s %d\n",stu[i].stuNo,stu[i].score);
    }
    return 0;
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值