• B правой части каждого сообщения есть стрелки и . Не стесняйтесь оценивать ответы. Чтобы автору вопроса закрыть свой тикет, надо выбрать лучший ответ. Просто нажмите значок в правой части сообщения.

  • Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Вывод Площади

  • Автор темы wanty
  • Дата начала
Статус
Закрыто для дальнейших ответов.
W

wanty

Задача заключается в построении площади по трём отрезкам, которые должны рандомно выбираться из рандомно сгенерированного массива. При этом нужно проверить все возможные комбинации вытягивания трёх чисел. Программа написана и работает, но ошибка в том, что перебирает не все комбинации, их количество должно определяться по формуле количества сочетаний (с факториалами), а у меня не получается, подскажите плиизз, что не так ? (Delphi)
вот части кода:
Код:
unit Unit2;
.
.
.
.

function LL.Plo(a, b, c: Double):Double;
var
p:Double;
begin
P:=(a+b+c)/2;
Result:=sqrt(p*(p-a)*(p-b)*(p-c));
end;

procedure LL.Proverka(var a, b, c: Variant; j:iNTEGER; N: Integer; h:array of Double);
begin
if (a=b) or (a=c) then
begin
j:=random(N);
a:=h[j];
end;
if (a=b) or (b=c) then
begin
j:=random(N);
b:=h[j];
end;

end;

end.




unit Unit1;
.
.
.
.

procedure TForm1.Button1Click(Sender: TObject);
var
h: array of Double;
N,i,j:integer;
a,b,c:Variant;
d: Double;
res:double;
begin
Try
if (edit1.text='') then raise EMessErr.Create('Число не введено');
if Edit1.text<>'' then
(Sender as Tbutton).Caption:='Рассчет площади выполнен';
if Edit1.text<Inttostr(3) then raise EMessErr.Create('Введите число >=3');
memo1.Lines.Clear;
memo2.Lines.Clear;
N:=StrToInt(Edit1.Text);
randomize;
setlength(h,N);
d:=1;
memo2.Lines.Add('Массив чисел');
for i:=0 to length(h)-1 do
begin
h[i]:=random*10;
memo2.Lines.Add(floattostr(h[i]));
End;
While D<>(N-1) do
begin
j:=random(N);
a:=h[j];
j:=random(N);
b:=h[j];
j:=random(N);
c:=h[j];
while (A=B) or (B=c) Or(A=c) do
Proverka (a,b,c,j,n,h);
if ( ( (a+b) <=c) or ( (b+c) <=a) or ( (c+a) <=b) ) then
else
begin
memo1.Lines.Add('выбранные числа');
memo1.Lines.Add(floattostr(a));
memo1.Lines.Add(floattostr(b));
memo1.Lines.Add(floattostr(c));
res:=Plo(a,b,c);
memo1.Lines.Add('Площадь треугольника равна'+Floattostr(res));
memo1.Lines.Add('------------------------------');
end;

d:=d+1
end;
.
.
.
.


.
 
N

nayke

Задача заключается в построении площади по трём отрезкам, которые должны рандомно выбираться из рандомно сгенерированного массива. При этом нужно проверить все возможные комбинации вытягивания трёх чисел.
Так ты определись или ты случайно вытягиваешь или все перебираешь.
 
W

wanty

Я имел виду что вытягиваются три любых числа из рандомно сгенерированного массива, но при этом перебираются все возможные комбинации трёх чисел из рандомно сгенерированного массива !
 
V

Vadik(R)

Запутался немного с рандомом, но вначале можно перебрать все комбинации, и запомнить их в массиве, например, а потом уже рандомно обращаться к этому массиву и помечать флагом наборы элементов, к которым ты уже обращался...
 
D

Dock1100

Рандомно генерим масив, хаотично его мешаем(по сути будет равносильно тому что елементы будут рандомно вытягиватся), перебираем все числа, правда если надо именно рандомно вытягивать, то я бы сделал масив типа:
Код:
type
MyMassElem=record
value:real;
flag:boolean;
end;

var
a:array[1..N] of MyMassElem;
в начале заполнял бы его нужными(в данном случае рандомными) числами, всем элементам выставил flag=false,
в цыкле рандомно генерил 3 разных чила, при обращении к елементу масива выставлял flag=true, при последуещем обращении проверял flag на равенство true , если равно генерил бы по новой, если нет брал бы нужный елемент, да и еще в самом начале нужно сделать переменную содержащюю длину масива, и при "взятии" елемента масива уменшал бы на 1, для того что б было условие выхода из цыкла. То есть так как предложыл Vadik®.
 
W

wanty

Спасибо конечно за идею, но это сложновато, по крайней мере для меня.Есть ещё какие либо варианты ?? Мне предлагали вариант с суммой чисел, и с факториалами, вот я пытаюсь разобраться с факториалами (формула числа сочетаний).
 
D

Dock1100

(формула числа сочетаний).
N*(N-1)*(N-2) где N количество сторон, (три множителя - три стороны)
Без рандомного "вытягивания" из масива:
Код:
const N=10;
var
s,p,a,b,c:real;
arr:array[1..N] of real;
i1,i2,i3:integer;
begin
for i1:=1 to N do
begin
arr[i1]:=(random(56)+1)/(random(35)+1);
//arr[i1]:=i1;
writeln('a[',i1,']=',arr[i1]:8:2);
end;
for i1:=1 to N-2 do
begin
a:=arr[i1];
for i2:=i1+1 to N-1 do
begin
b:=arr[i2];
for i3:=i2+1 to N do
begin
c:=arr[i3];
p:=(a+b+c)/2;
//s:=sqrt(p*(p-a)*(p-b)*(p-c));//что б нормально посчитать площадь надо нормально сгенерировать масив, дабы для каждой тройки сторон выполнялись условия a+b>c  b+c>a  c+a>b
writeln(' a=',a:3:2,' b=',b:3:2,' c=',c:3:2,'  square=',s:3:2);
end;
end;
end;
readln;
end.
 
Статус
Закрыто для дальнейших ответов.
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!