#include #include // 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++; } } 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) { 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; // Развертывание цикла (Unrolling) + Избавление от if (Branchless) // Процессор будет выполнять эти операции параллельно в конвейере int j = 0; // Разворачиваем по 2 шага для ускорения for (; j <= count - 2; j += 2) { current_sum += (long long)numbers[j] * ((i >> j) & 1); current_sum += (long long)numbers[j + 1] * ((i >> (j + 1)) & 1); } // Добираем оставшиеся элементы, если count не кратен 2 for (; j < count; j++) { current_sum += (long long)numbers[j] * ((i >> j) & 1); } if (current_sum == target) { ten_to_bin(count, i, mask); printf("OK: %s\n", mask); return; } } printf("NO: not found.\n"); } void find_sum_old(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++) { // Используем умножение на бит вместо if, чтобы избежать ошибок в предсказании перехода current_sum += numbers[j] * ((i >> j) & 1); } if (current_sum == target) { ten_to_bin(count, i, mask); printf("OK: %s\n", mask); return; } } printf("NO: not found.\n"); } // gcc -O3 -march=bdver2 solution4.c -o solution // gcc -O3 solution4.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; }