april_day_2026/c/solution3.c
2026-03-28 18:14:27 +03:00

92 lines
2.9 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 <stdlib.h> // atoi, malloc
void ten_to_bin(int count, long long x, char *mask) {
int i = 0;
while (i < count) {
mask[i] = (x & 1) + '0'; // Побитовое И вместо % 2
mask[i+1] = '\0';
x >>= 1; // Побитовый сдвиг вправо вместо / 2
i++;
}
}
/*
* Оптимизированный подсчет суммы:
* Проверяем биты числа x напрямую. Если j-й бит равен 1,
* прибавляем numbers[j] к сумме.
*/
long long calculate_sum(int count, int *numbers, long long x) {
long long sum = 0;
for (int j = 0; j < count; j++) {
// Проверяем, установлен ли j-й бит в числе x
if ((x >> j) & 1) {
sum += numbers[j];
}
}
return sum;
}
void find_sum(int count, long long target, int *numbers, char *mask) {
// 1LL << count — это 2 в степени count (макс. 62 для long long)
long long total_combinations = (1LL << count);
printf("Total combinations: %lld\n", total_combinations);
for (long long i = 0; i < total_combinations; i++) {
long long current_sum = 0;
// Внутренний цикл: проверяем биты числа i напрямую
for (int j = 0; j < count; j++) {
// Если j-й бит числа i равен 1, прибавляем numbers[j]
if ((i >> j) & 1) {
current_sum += numbers[j];
}
}
if (current_sum == target) {
ten_to_bin(count, i, mask);
printf("OK: %s\n", mask);
return;
}
}
printf("NO: not found.\n");
}
// gcc -O3 solution3.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
char *mask =
calloc(count + 1, sizeof(char)); // +1 для символа конца строки '\0'
// 4. Данные готовы, начинаем считать
find_sum(count, target, numbers, mask);
// 5. Освобождаем память
free(mask);
free(numbers);
return 0;
}