PTA - C编程 NoE - 结构(10道题)

6-1 计算两个复数之积

struct complex multiply(struct complex x, struct complex y)
{
	struct complex res;
	res.real = x.real * y.real - x.imag * y.imag;
	res.imag = x.real * y.imag + x.imag * y.real;
	return res;
}

6-2 按等级统计学生成绩

int set_grade(struct student *p, int n)
{
	int res = 0;
	for(int i = 0; i < n; i++)
	{
		if(p[i].score >= 85)      p[i].grade = 'A';
		else if(p[i].score >= 70) p[i].grade = 'B';
		else if(p[i].score >= 60) p[i].grade = 'C';
		else
		{
			p[i].grade = 'D';
			++res;
		}
	}
	return res;
}

7-1 计算职工工资

#include <stdio.h>
struct clerk
{
	char name[10];  // name为长度小于10的不包含空白字符的非空字符串
	double basic_wage, floating_wage, expenditure, real_wage;
};

int main()
{
	int n;
	scanf("%d", &n);
	struct clerk ck;
	for(int i = 0; i < n; i++)
	{
		scanf("%s%lf%lf%lf", ck.name, &ck.basic_wage, &ck.floating_wage, &ck.expenditure);
		ck.real_wage = ck.basic_wage + ck.floating_wage - ck.expenditure;
		printf("%s %.2lf\n", ck.name, ck.real_wage);
	}
	return 0;
}

7-2 时间换算

  因为需要用两位输出时分秒,也就是 ‘0’ 需要输出为 ‘00’,所以用 %02d 来控制输出

#include <stdio.h>
struct Time
{
	int hour, minute, second;
};

int main()
{
	int time_passed;  // 过了多少时间,小于60
	struct Time t;
	scanf("%d:%d:%d%d", &t.hour, &t.minute, &t.second, &time_passed);
	int carry1 = (t.second + time_passed) / 60; // 计算秒上的进位
	t.second = (t.second + time_passed) % 60;   // 计算新的时间的秒位
	int carry2 = (t.minute + carry1) / 60;      // 计算分上的进位
	t.minute = (t.minute + carry1) % 60;        // 计算新的时间的分位
	t.hour = (t.hour + carry2) % 24;            // 计算新的时间的时位
	printf("%02d:%02d:%02d\n", t.hour, t.minute, t.second);
	return 0;
}

7-3 计算平均成绩

解:
  因为要求输出他们的平均成绩,顺序输出平均线以下的学生名单,所以不能挨个判断然后输出,也就只能用结构体数组了。

#include <stdio.h>
struct student
{
    char num[6];    // 学号(由5个数字组成的字符串)
    char name[10];  // 姓名(长度小于10的不包含空白字符的非空字符串)
    int grade;      // 成绩([0,100]区间内的整数)
};

int main()
{
    int n;
    double average = 0.0;
    scanf("%d", &n);
    struct student stu[n];
    for(int i = 0; i < n; i++)
    {
        scanf("%s %s %d", stu[i].num, stu[i].name, &stu[i].grade);
        average += stu[i].grade;
    }
    average /= (double)n;
    printf("%.2lf\n", average);
    for(int i = 0; i < n; i++)
        if(stu[i].grade < average)
            printf("%s %s\n", stu[i].name, stu[i].num);
    return 0;
}

7-4 查找书籍

  长度不超过 30 的字符串需要用 31 大小的字符数组存放而且用 gets 读取字符串的时候,一定要读掉前边的换行符,负责会只读到这个换行符

#include <stdio.h>
int main()
{
    int n, max_idx = 0, min_idx = 0;
    char book_name[10][35];
    double book_price[10];
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        getchar();  // 要读掉 gets 前边的换行符
        gets(book_name[i]);
        scanf("%lf", &book_price[i]);
        if(book_price[i] > book_price[max_idx])  max_idx = i;
        else                                     min_idx = i;
    }
    printf("%.2lf, %s\n", book_price[max_idx], book_name[max_idx]);
    printf("%.2lf, %s\n", book_price[min_idx], book_name[min_idx]);
    return 0;
}

7-5 有理数比较

  其实直接用 double 记录除法结果进行比较就可以,但是我觉得可能会出现精度错误,所以把两个分母变成一样大,比较变化后的分子的方式来判断,两种方法在这道题的测试用例中都可以通过。

#include <stdio.h>
long long LCM(int a, int b) // 计算最小公倍数 Least Common Multiple
{
    int start;
    if(a < b) start = b;
    else      start = a;
    for(long long i = start; ; i++)
        if(i % a == 0 && i % b == 0)
            return i;
}
int main()
{
    int a1, b1, a2, b2;
    scanf("%d/%d %d/%d", &a1, &b1, &a2, &b2);
    long long lcm = LCM(b1, b2);
    long long a1_new = lcm / b1 * a1, a2_new = lcm / b2 * a2;
    //double a_res = a1 * 1.0 / b1, b_res = a2 * 1.0 / b2;
    //if(a_res > b_res)      printf("%d/%d > %d/%d\n", a1, b1, a2, b2);
    //else if(a_res < b_res) printf("%d/%d < %d/%d\n", a1, b1, a2, b2);
    //else                   printf("%d/%d = %d/%d\n", a1, b1, a2, b2);
    if(a1_new > a2_new)       printf("%d/%d > %d/%d\n", a1, b1, a2, b2);
    else if(a1_new < a2_new)  printf("%d/%d < %d/%d\n", a1, b1, a2, b2);
    else                      printf("%d/%d = %d/%d\n", a1, b1, a2, b2);
    return 0;
}

7-6 平面向量加法

  需要知道的是 %.1f 会自动进行四舍五入,0.05 变成 0.1, -0.05 变成 -0.1,-0.04 变成 -0.0,所以对于 -0.0 这种情况,不是说值是 0,而是 -0.04 这种小于0,但是又大于 -0.05 的情况,把这种情况设为0,即可。

#include<stdio.h>
int main()
{
	double x1, y1, x2, y2, m, n;
	scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
	m = x1 + x2;
	n = y1 + y2;
	if(m > -0.05 && m < 0) m = 0;
	if(n > -0.05 && n < 0) n = 0;
    printf("(%.1lf, %.1lf)\n", m, n);	
	return 0;
}

7-7 找出总分最高的学生

#include <stdio.h>
struct student
{
    char num[6];    // 学号(由5个数字组成的字符串)
    char name[10];  // 姓名(长度小于10的不包含空白字符的非空字符串)
    int grade1, grade2, grade3;  // 成绩([0,100]区间内的整数)
};
int main()
{
    int n, top_sum = 0;       // 最高的总分
    scanf("%d", &n);
    struct student top, tmp;  // top: 总分最高的学生, tmp: 每次读的student变量
    for(int i = 0; i < n; i++)
    {
        scanf("%s %s %d %d %d", tmp.num, tmp.name, &tmp.grade1, &tmp.grade2, &tmp.grade3);
        if(tmp.grade1 + tmp.grade2 + tmp.grade3 > top_sum)
        {
            top_sum = tmp.grade1 + tmp.grade2 + tmp.grade3;
            strcpy(top.num, tmp.num);
            strcpy( top.name, tmp.name);
            // 三门课的成绩不需要,只记录总分即可
        }
    }
    printf("%s %s %d\n", top.name, top.num, top_sum);
    return 0;
}

7-8 找出总分最高的学生

  其实就是正常的插入排序,只不过对象换成了结构体。

#include <stdio.h>
#include <string.h>
struct friends
{
    char name[11]; // 长度不超过10的英文字母组成的字符串
    int birthday;  // yyyymmdd格式的日期, 因为肯定是1开头,所以可以用 int 存放
    char tel[18];  // 不超过17位的数字及+、-组成的字符串
};
int main()
{
    int n, cur = 0;
    scanf("%d", &n);
    struct friends f[n];
    for(int i = 0; i < n; i++)  // 用 birthday 进行插入排序, birthday 大年纪就小
    {
        struct friends tmp;
        scanf("%s %d %s", tmp.name, &tmp.birthday, tmp.tel);
        int j;
        for(j = 0; j < cur; j++)
            if(tmp.birthday < f[j].birthday)
            {
                for(int k = cur; k > j; k--)
                {
                    strcpy(f[k].name, f[k - 1].name);
                    f[k].birthday = f[k - 1].birthday;
                    strcpy(f[k].tel, f[k - 1].tel);
                }
                strcpy(f[j].name, tmp.name);
                f[j].birthday = tmp.birthday;
                strcpy(f[j].tel, tmp.tel);
                break;
            }
        if(j == cur)
        {
            strcpy(f[cur].name, tmp.name);
            f[cur].birthday = tmp.birthday;
            strcpy(f[cur].tel, tmp.tel);
        }
        ++cur;
    }
    for(int i = 0; i < n; i++)
        printf("%s %d %s\n", f[i].name, f[i].birthday, f[i].tel);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值