Задано n произвольных натуральных чисел.
Найти все суммы по k чисел, сумма которых равна заданному числу m.
Программа.
Архив программы для wxDev-C++.
Код программы.
Проверка нахождения всх сочетаний из n элементов по k элементов.
Данная программа создаст массив из n случайных натуральных чисел из множества
1..max, где числа
max,
n задаются с клавиатуры. После этого задаётся число слагаемых
k и натуральное число
m, которое не меньше числа слагаемых
k и не больше произведения
k*max. Программа вычисляет всевозможные суммы из
k слагаемых, сравнивает эти суммы с заданным числом
m и выводит на экран и в текстовый файл
сomb.txt номера индексов тех элементов массива, сумма которых равна заданному числу
m.
Вводится число
n – количество элементов массива
x[i].
Вводится максимальное натуральное число
max, которое может присутствовать среди этих чисел.
Вводится число слагаемых в суммах
k. При этом проверяется условие
1<=k<=n. В том случае, если это условие не выполняется, происходит повторный ввод этого числа.
Вводится заданное число
m. При этом проверяется условие
k<=m<=max*k. В том случае, если это условие не выполняется, происходит повторный ввод этого числа.
После этого вводится массив
x[i] из n случайных натуральных чисел, не превосходящих числа
max. Индекс
i меняется при этом от
1 до
n в цикле.
После этого вводится массив из
k индексов
a[i] для
k слагаемых в сумме. В начальной конфигурации все эти индексы следуют по порядку друг за другом от
1 до
k. Индекс
i меняется при этом от
1 до
k в цикле
for (i=0; i ≤ k; i++) a[i]=i; .
Далее присваиваются нулевые значения элементам
p,
r,
z,
c.
c – это количество сочетаний из
n элементов по
k элементов, то есть общее количество сумм из
k слагаемых.
z – количество сумм, равных заданному элементу
m.
p – переменная, указывающая, сколько элементов индексов в конце массива индексов удовлетворяют условию:
a[k-p]==n-p, то есть последний элемент
a[k] в списке
a[1]..a[k] равен последнему номеру
n , предпоследний
a[k-1] равен
n-1, … ,
p-й индекс с конца
a[k-p] равен
n-p. Значение переменной
p будет меняться от
0 до
k-1.
Далее следует большой цикл, который будет завершён тогда, когда значение переменной
p станет равным
k-1. Этот цикл закончится тогда, когда все
k индексов в сумме станут располагаться по порядку друг за другом, и на последнем месте будет стоять индекс
a(n), на предпоследнем
a(n-1), … , на первом месте
a(n-k+1).
Вычисляется сумма
k слагаемых
x[a[1]]+x[a[2]]+…+x[a[k]], и если эта сумма равна заданному числу
m, то значения индексов слагаемых суммы выводится на экран и в файл. Если число заданное количество элементов массива
n больше заданного количества слагаемых в сумме
k (
k<n), то в самой первой сумме, когда слагаемые располагались по порядку друг за другом
a[1]=1, a[2]=2, … a[k]=k, а
p=0, условие
a[k-p]==n-p не выполняется, и значение последнего индекса
a[k] увеличивается на единицу (
a[k-p]++), после чего снова подсчитывается сумма
k слагаемых
x[a[1]]+x[a[2]]+… +x[a[k]], и если эта сумма равна заданному числу
m, то значения индексов слагаемых суммы выводится на экран и в файл.
(Цикл
for (r=0; r<p; r++) a[k-p+r+1]=a[k-p+r]+1; не выполняется ни разу при условии
p==0).
Так продолжается до тех пор, пока последний индекс
a[k]не станет равным
n.
Как только начнёт выполняться условие
a[k]==n (то есть
a[k-p]==n-p при
p==0), значение
p увеличивается на единицу и принимает значение
1.
Если заданное
n значительно больше заданного
k, то при
p==1 условие
a[k-p]==n-p не выполняется, и значение предпоследнего индекса
a[k-1] увеличивается на единицу
a[k-1]= a[k-1]+1 (
a[k-p]++ при
p==1), а значение последнего индекса устанавливается на единицу больше значения предпоследнего индекса
a[k]=a[k-1]+1 (это будет достигнуто благодаря однократному выполнению цикла
for (r=0; r<p; r++) a[k-p+r+1]=a[k-p+r]+1; при значениях
p==1,
r==0).
После этого значение
p присваивается нулевое значение и повторяется цикл с увеличением на 1 последнего индекса
a[k].
На определённом этапе выполнения этого алгоритма может оказаться так, что
p индексов подряд, начиная с конца массива индексов, удовлетворяют следующему условию:
a[k]==n, a[k-1]==n-1, a[k-2]==n-2, a[k-3]==n-3, … , a[k-p+1]==n-p+1,
но значение
a[k-p] не равно
n-p. Тогда происходит увеличение на единицу этого индекса
a[k-p], а следующие за ним
p индексов будут расположены по порядку возрастания на 1 друг за другом, то есть
a[k-p+1]=a[k-p]+1, a[k-p+2]=a[k-p+1]+1, a[k-p+3]= a[k-p+2]+1, … , a[k-1]=a[k-2]+1; a[k]=a[k-1]+1. )
Это произойдёт благодаря выполнению
p раз цикла
for (r=0; r<p; r++) a[k-p+r+1]=a[k-p+r]+1).
Большой цикл завершится при выполнении условия
a(k)==n, a(k-1)==n-1, a(k-2)==n-2, …, a(1)==n-k+1
На экран и в файл будут выведены всевозможные суммы из по
k чисел, сумма которых равна заданному числу
m.
После этого на экран и в файл выводятся количество таких сумм
z, равных числу
m, и общее количество сумм
c