Тренировочные задания: Структуры и пользовательские типы
Десять задач на структуры, массивы структур, typedef, enum и union.
Данные — только числа: без строк, char[] и strcmp.
Задача 1. Запись Student
Опишите структуру Student (id, course, score), считайте одну запись и выведите её.
Пример ввода:
1 2 4.5
Пример вывода:
1 2 4.50
Решение
#include <stdio.h>
typedef struct
{
int id;
int course;
double score;
} Student;
int main(void)
{
Student s;
if (scanf("%d %d %lf", &s.id, &s.course, &s.score) != 3)
{
return 1;
}
printf("%d %d %.2f\n", s.id, s.course, s.score);
return 0;
}
Задача 2. Средний балл группы
Считайте N записей в динамический массив и выведите средний score.
Пример ввода:
2
1 2 4.5
2 2 3.5
Пример вывода:
4.00
Решение
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int id;
int course;
double score;
} Student;
int main(void)
{
int n;
if (scanf("%d", &n) != 1 || n <= 0)
{
return 1;
}
Student *group = malloc((size_t)n * sizeof(*group));
if (group == NULL)
{
return 1;
}
double sum = 0.0;
for (int i = 0; i < n; i++)
{
if (scanf("%d %d %lf",
&group[i].id,
&group[i].course,
&group[i].score) != 3)
{
free(group);
return 1;
}
sum += group[i].score;
}
printf("%.2f\n", sum / n);
free(group);
return 0;
}
Задача 3. Лучшая запись
Найдите запись с максимальным score.
Пример ввода:
3
1 1 4.1
2 1 4.9
3 1 4.5
Пример вывода:
2 4.90
Решение
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int id;
int course;
double score;
} Student;
int main(void)
{
int n;
if (scanf("%d", &n) != 1 || n <= 0)
{
return 1;
}
Student *group = malloc((size_t)n * sizeof(*group));
if (group == NULL)
{
return 1;
}
for (int i = 0; i < n; i++)
{
if (scanf("%d %d %lf",
&group[i].id,
&group[i].course,
&group[i].score) != 3)
{
free(group);
return 1;
}
}
int best = 0;
for (int i = 1; i < n; i++)
{
if (group[i].score > group[best].score)
{
best = i;
}
}
printf("%d %.2f\n", group[best].id, group[best].score);
free(group);
return 0;
}
Задача 4. Сортировка по score
Отсортируйте записи по убыванию score.
Пример ввода:
3
1 1 4.1
2 1 4.9
3 1 4.5
Пример вывода:
2 1 4.90
3 1 4.50
1 1 4.10
Решение
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int id;
int course;
double score;
} Student;
int main(void)
{
int n;
if (scanf("%d", &n) != 1 || n <= 0)
{
return 1;
}
Student *group = malloc((size_t)n * sizeof(*group));
if (group == NULL)
{
return 1;
}
for (int i = 0; i < n; i++)
{
if (scanf("%d %d %lf",
&group[i].id,
&group[i].course,
&group[i].score) != 3)
{
free(group);
return 1;
}
}
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - 1 - i; j++)
{
if (group[j].score < group[j + 1].score)
{
Student tmp = group[j];
group[j] = group[j + 1];
group[j + 1] = tmp;
}
}
}
for (int i = 0; i < n; i++)
{
printf("%d %d %.2f\n", group[i].id, group[i].course, group[i].score);
}
free(group);
return 0;
}
Задача 5. Поиск по id
Считайте N записей и id; выведите запись или -1, если её нет.
Пример ввода:
2
1 1 4.1
2 2 4.9
2
Пример вывода:
2 2 4.90
Решение
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int id;
int course;
double score;
} Student;
int main(void)
{
int n;
if (scanf("%d", &n) != 1 || n <= 0)
{
return 1;
}
Student *group = malloc((size_t)n * sizeof(*group));
if (group == NULL)
{
return 1;
}
for (int i = 0; i < n; i++)
{
if (scanf("%d %d %lf",
&group[i].id,
&group[i].course,
&group[i].score) != 3)
{
free(group);
return 1;
}
}
int query;
if (scanf("%d", &query) != 1)
{
free(group);
return 1;
}
for (int i = 0; i < n; i++)
{
if (group[i].id == query)
{
printf("%d %d %.2f\n", group[i].id, group[i].course, group[i].score);
free(group);
return 0;
}
}
printf("-1\n");
free(group);
return 0;
}
Задача 6. Количество по курсам
Для каждого курса посчитайте количество записей. Выведите только непустые курсы.
Пример ввода:
4
1 1 4.1
2 2 4.9
3 1 4.5
4 3 4.0
Пример вывода:
1: 2
2: 1
3: 1
Решение
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int id;
int course;
double score;
} Student;
int main(void)
{
int n;
if (scanf("%d", &n) != 1 || n <= 0)
{
return 1;
}
Student *group = malloc((size_t)n * sizeof(*group));
if (group == NULL)
{
return 1;
}
int count[7] = { 0 };
for (int i = 0; i < n; i++)
{
if (scanf("%d %d %lf",
&group[i].id,
&group[i].course,
&group[i].score) != 3)
{
free(group);
return 1;
}
if (group[i].course >= 1 && group[i].course <= 6)
{
count[group[i].course]++;
}
}
for (int c = 1; c <= 6; c++)
{
if (count[c] > 0)
{
printf("%d: %d\n", c, count[c]);
}
}
free(group);
return 0;
}
Задача 7. Следующий день
Опишите структуру Date и выведите следующий день. Учитывайте високосные годы.
Пример ввода:
28 2 2024
Пример вывода:
29.02.2024
Решение
#include <stdio.h>
typedef struct
{
int day;
int month;
int year;
} Date;
int days_in_month(int month, int year)
{
int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (month == 2 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))
{
return 29;
}
return days[month - 1];
}
int main(void)
{
Date d;
if (scanf("%d %d %d", &d.day, &d.month, &d.year) != 3)
{
return 1;
}
d.day++;
if (d.day > days_in_month(d.month, d.year))
{
d.day = 1;
d.month++;
if (d.month > 12)
{
d.month = 1;
d.year++;
}
}
printf("%02d.%02d.%04d\n", d.day, d.month, d.year);
return 0;
}
Задача 8. Сложение комплексных чисел
Опишите структуру Complex и функцию сложения.
Пример ввода:
1 2
3 4
Пример вывода:
4 + 6i
Решение
#include <stdio.h>
typedef struct
{
double re;
double im;
} Complex;
Complex add(Complex a, Complex b)
{
Complex result;
result.re = a.re + b.re;
result.im = a.im + b.im;
return result;
}
int main(void)
{
Complex a, b;
if (scanf("%lf %lf %lf %lf", &a.re, &a.im, &b.re, &b.im) != 4)
{
return 1;
}
Complex c = add(a, b);
printf("%g + %gi\n", c.re, c.im);
return 0;
}
Задача 9. Расстояние между точками
Опишите структуру Point и функцию расстояния. Используйте sqrt из math.h;
при сборке может понадобиться -lm.
Пример ввода:
0 0
3 4
Пример вывода:
5.00
Решение
#include <math.h>
#include <stdio.h>
typedef struct
{
double x;
double y;
} Point;
double distance_between(Point a, Point b)
{
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
int main(void)
{
Point a, b;
if (scanf("%lf %lf %lf %lf", &a.x, &a.y, &b.x, &b.y) != 4)
{
return 1;
}
printf("%.2f\n", distance_between(a, b));
return 0;
}
Задача 10. Tagged union
Опишите Value (enum + union для int/double) и выведите значения с типом:
1 — int, 2 — double.
Пример ввода:
3
1 42
2 3.14
1 -7
Пример вывода:
1 42
2 3.14
1 -7
Решение
#include <stdio.h>
typedef enum
{
VALUE_INT = 1,
VALUE_DOUBLE = 2
} ValueType;
typedef struct
{
ValueType type;
union
{
int i;
double d;
} as;
} Value;
int main(void)
{
int n;
if (scanf("%d", &n) != 1 || n < 0)
{
return 1;
}
for (int k = 0; k < n; k++)
{
int type;
if (scanf("%d", &type) != 1)
{
return 1;
}
if (type == VALUE_INT)
{
int x;
if (scanf("%d", &x) != 1)
{
return 1;
}
printf("%d %d\n", VALUE_INT, x);
}
else if (type == VALUE_DOUBLE)
{
double x;
if (scanf("%lf", &x) != 1)
{
return 1;
}
printf("%d %.2f\n", VALUE_DOUBLE, x);
}
else
{
return 1;
}
}
return 0;
}