april_day_2026/c/solution1_comments.c

121 lines
4.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <math.h> // pow
#include <stdlib.h> // atoi, malloc
/*
* name: ten_to_bin
*
* Описание: Преобразует целое число в строку из символов '0' и '1' (двоичный
* вид). Биты записываются в обратном порядке (от младшего к старшему). В конец
* строки всегда добавляется нулевой символ '\0'.
*
* @param count - Максимальное количество бит для обработки.
* @param x - Число для конвертации (передается по значению).
* @param mask - Указатель на буфер, куда записывается строка (размер >= count
* + 1).
*
* @return void (результат сохраняется напрямую в памяти по адресу mask).
*/
void ten_to_bin(int count, int x, char *mask) {
int i = 0;
while (x != 0 && i < count) {
// Превращаем 0 в '0' (код 48), 1 в '1' (код 49)
mask[i] = (x % 2) + '0';
mask[i+1] = '\0';
x /= 2;
i++;
}
}
/*
* name: calculate_sum
*
* Описание: Вычисляет сумму чисел из массива numbers, соответствующих
* символу '1' в битовой строке mask.
*
* @param count - Максимальное количество элементов для проверки.
* @param numbers - Указатель на массив исходных целых чисел.
* @param mask - Строка (char*), где '1' означает "включить число в сумму",
* а '0' — "пропустить".
*
* @return int - Итоговая сумма выбранных чисел.
*/
int calculate_sum(int count, int *numbers, char *mask) {
int x = 0;
for (int i = 0; mask[i] != '\0' && i < count; i++) {
if (mask[i] == '1') {
x += numbers[i];
}
}
return x;
}
/*
* name: find_sum
*
* Описание: Перебирает все возможные комбинации чисел (через двоичные маски),
* пока не найдет ту, сумма которой равна target.
* При нахождении выводит маску в консоль и завершает работу.
*
* @param count - Количество чисел в исходном массиве.
* @param target - Целевая сумма, которую нужно получить.
* @param numbers - Указатель на массив исходных чисел.
* @param mask - Буфер для хранения и вывода текущей битовой комбинации.
*
* @return void (результат выводится в стандартный поток вывода printf).
*/
void find_sum(int count, long long target, int *numbers, char *mask) {
long long total_combinations = pow(2, count) - 1;
printf("Total combinations: %lld\n", total_combinations);
for (int i = 0; i <= total_combinations; i++) {
ten_to_bin(count, i, mask);
long long current_sum = calculate_sum(count, numbers, mask);
if (current_sum == target) {
// Печать результата
printf("OK: %s\n", mask);
return;
}
}
printf("NO: not found.\n");
}
// gcc -O3 solution1.c -o solution -lm
// ./solution 477550 15800 1525 35300 19410 25000 15800 1525 35300 19410 25000
// 15800 1525 35300 19410 25000 15800 1525 35300 19410 25000 15800 1525 35300
// 19410 25000
int main(int argc, char *argv[]) {
// 1. Валидация ввода
if (argc < 5) {
printf("ER: input parameters \n");
return 1;
}
if (argc > 30) {
printf("ER: input parameters \n");
return 1;
}
// 2. Формирование массива int
long long target = atoi(argv[1]); // Требуемая сумма
int count = argc - 2; // Количество переданных чисел
int *numbers = malloc(count * sizeof(int)); // Массив чисел
for (int i = 0; i < count; i++) {
// Преобразуем каждый аргумент (начиная с argv[2]) в int
numbers[i] = atoi(argv[i + 2]);
}
// 3. Формирование массива char
// +1 для символа конца строки '\0'
char *mask = calloc(count + 1, sizeof(char));
// 4. Данные готовы, начинаем считать
find_sum(count, target, numbers, mask);
// 5. Освобождаем память
free(mask);
free(numbers);
return 0;
}