Программа составления вектора из фиксированного набора чисел - Turbo Pascal
Формулировка задачи:
Прошу помощи или подсказки в написании программы, которая бы из 2000 (фиксированно) чисел от 1 до 20 (возможен и другой близкий диапазон значений) составляла бы вектор, сумма всех элементов которого равнялась бы 40000 (fixed).
Пишу программу на матлабе, но задача больше для программистов, поэтому и обращаюсь сюда.
В идеале числа должны выбираться случайно из набора 1-20 или любого другого, как я описал выше. Но я могу их потом случайным образом и перемешать. Главное алгоритм. У меня никак не сходится по параметрам: кол-во чисел в векторе (2000) и сумма всех элементов (40000), которые жестко зафиксированы.
Решение задачи: «Программа составления вектора из фиксированного набора чисел»
textual
Листинг программы
{$MODE TP}
function RandomInRange(const a, b: Integer): Integer;
begin
RandomInRange := Random(b - a + 1) + a;
end;
var
randId, i, n: Word;
sum, reqSum: LongInt;
temp: Integer;
ar: Array[Word] Of Integer;
a, b: Byte; //диапазон значений
begin
Randomize;
repeat
Write('Input array length: ');
ReadLn(n);
until (n > 0);
Write('Input sum: '); ReadLn(reqSum);
Write('Input left boundary: '); ReadLn(a);
repeat
Write('Input right boundary (>=', a, '): ');
ReadLn(b);
until (b >= a);
//начальное генерирование
sum := 0;
for i := 0 to n - 1 do
begin
ar[i] := RandomInRange(a, b);
Inc(sum, ar[i]);
end;
//зацикливаемся пока не выйдем на нужную сумму
while (sum <> reqSum) do
begin
repeat
randId := RandomInRange(0, n - 1);
until (((sum > reqSum) And (ar[randId] > a)) Or ((sum < reqSum) And (ar[randId] < b))); //рандомно выбираем элемент попутно делая проверку есть ли смысл менять текущий элемент (к примеру, при недоборе суммы нет смысла менять максимальный элемент)
temp := ar[randId];
if (sum > reqSum)
then //если перебор
ar[randId] := RandomInRange(a, ar[randId] - 1) //уменьшаем в пределах left <= x < current
else //если недобор
ar[randId] := RandomInRange(ar[randId] + 1, b); //увеличиваем в пределах current < x <= right
sum := sum - temp + ar[randId]; //пересчитываем сумму
end;
//вывод окончательного массива
Write('Generated array:');
for i := 0 to n - 1 do
Write(' ', ar[i]);
end.