#include #include // pow #include // 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; }