Compare commits
No commits in common. "d3ac3e74fbfb85c2ca40e90b8c48d3b99a21c59b" and "defed24cd060565c091443f0d47d37a77070ff28" have entirely different histories.
d3ac3e74fb
...
defed24cd0
2 changed files with 0 additions and 209 deletions
|
|
@ -1,92 +0,0 @@
|
||||||
#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;
|
|
||||||
}
|
|
||||||
117
c/solution4.c
117
c/solution4.c
|
|
@ -1,117 +0,0 @@
|
||||||
#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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue