Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Алгоритмы _ Дверь и шкаф

Автор: sheka 13.09.2010 21:37

Вопрос: возможно ли пронести шкаф a*b*c через дверь p*q?
Мое решение:

write ( min(a,min(b,c)) < min(p,q))  and  (a+b+c-min(a,min(b,c))-max(a,max(b,c)) < max(p,q) );

Можно как-то оптимизировать? Учитывая, что паскаль я вижу впервые, и что я функции, по идее, знать не должен программа растягивается до некультурной длины.

Автор: sheka 13.09.2010 23:12

маленький упс.. там же можно еще и в плоскостях шкаф передвигать наверное..

Автор: Unconnected 13.09.2010 23:46

Для протаскивания шкафа нужно, чтобы 2 из 3х его параметров удовлетворяли двери. Можно упорядочить стороны по возрастанию и взять первые 2 числа, а потом их уже сравнивать с дверью.. Правда, широкий низкий шкаф, который просто так по ширине не проходит, можно пронести, немного повернув его)

Автор: sheka 14.09.2010 1:40

Готово. Чуть позже постараюсь выложить объяснения.

procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,p,q:real;
begin
a:=strtofloat(edit1.text);
b:=strtofloat(edit2.Text);
c:=strtofloat(edit3.Text);
if a<b then
begin
p:=a;
if c<b then q:=c
else q:=b;
end
else
begin
p:=b;
if c<a then q:=c
else q:=a;
end;
if p>q then begin a:=p; b:=q; end
else begin a:=q; b:=p; end;

p:=strtofloat(edit4.Text);
q:=strtofloat(edit5.Text);
if p>q then begin c:=p; p:=q; q:=c; end;

if a>q then
if p>= sqrt(a*a+b*b)*sin(arctan(2*a*b/(a*a-b*b))+arctan(sqrt(a*a+b*b-q*q)/q)) then
button1.Caption:='Can'
else button1.Caption:='Can''t'
else
if (b<=p) then button1.Caption:='Can'
else button1.Caption:='Can''t';
end;

Автор: Lapp 14.09.2010 6:20

Ребят, раздел - Алгоритмы! Программа - не есть алгоритм, она есть его реализация. Если вы кладете тут программу, то только как демонстрацию ранее приведенного алгоритма!

Даю возможность исправить ошибку задним числом.. ))

Автор: TarasBer 14.09.2010 15:51

> sqrt(a*a+b*b)*sin(arctan(2*a*b/(a*a-b*b))+arctan(sqrt(a*a+b*b-q*q)/q))

То есть ты решил учесть поворот?
Мне кажется, тут какая-то лажа.
Потому что второе слагаемое arctan(sqrt(...)) имеет не ту размерность.
Кстати, sin(arctan(x)) = x/sqrt(sqr(x)+1), причём корень тут берётся.
т.е. можно выражение очень упростить.
Первое слагаемое (sqrt(a*a+b*b)*sin(arctan(2*a*b/(a*a-b*b))) сожмётся до 2ab/sqrt(aa+bb)

Автор: sheka 15.09.2010 2:11

TarasBer, там же, как ты сам и говорил, сумма арктангенсов. а еще играться с триногометрией.. я думаю там не проще будет.
Lapp, как мне сегодня рассказывали, программа - один из вариантов представления алгоритма. smile.gif
Я бы с удовольствием выложил алгоритм, но его надо сначало красиво переписать))) Сделаю чуть позже.

TarasBer, проверяй, пожалуйста. Вроде все чики пики. Я вчера ночером по миллиметрам линейкой считал: Прикрепленный файл  ____________.rar ( 176.59 килобайт ) Кол-во скачиваний: 664

Автор: TarasBer 15.09.2010 15:37

А, второй арктангенс под синусом. Понял.
Тогда так
sin(x+y)=sinxcosy+sinycosx=
(2abq+(a2-b2)sqrt(a2+b2-q2))/(a2+b2)sqrt(a2+b2)
После умножения на sqrt(a2+b2) из знаменателя исчезает корень:

if p*(a*a+b*b)>= 2*a*b*q+(a*a+b*b)*sqrt(a*a+b*b-q*q) then...

Кстати, в таком виде формула уже не вылетает при a=b.
Но симметрии всё равно пока нет. Надо дальше думать.

Автор: TarasBer 15.09.2010 19:50

После симметризации условие принимает вид такой:
(p2+q2)*(a2+b2)-4pqab>=
(a2+b2)*(a2+b2)-4abab.

Автор: sheka 20.09.2010 4:53

      alpha := arctan(sqrt(a*a+b*b-q*q)/q);
if a=b then beta := pi/2
else beta := arctan(2*a*b/(a*a-b*b));
d := sqrt(a*a+b*b);
h := d*sin(alpha+beta);
if (alpha+beta<pi/2)and(p >= h) then

Добавил такие ограничения, вроде уже при всех входных данных должно работать. С первого раза как-то забыл проверить..
TarasBer, можешь подробнее расписать, не могу уловить ход размышлений smile.gif
Lapp, вот только добрался, и написал "алгоритм" smile.gifПрикрепленное изображение

Автор: sheka 21.09.2010 0:57

Вот никак не могу понять, откуда из вот этого

Цитата
p*(a*a+b*b)>= 2*a*b*q+(a*a+b*b)*sqrt(a*a+b*b-q*q)
берется вот это:
Цитата
После симметризации условие принимает вид такой:
(p2+q2)*(a2+b2)-4pqab>=
(a2+b2)*(a2+b2)-4abab.

Автор: TarasBer 23.09.2010 22:17

Переносим 2*a*b*q налево, возводим в квадрат.
Потом, после приведения подобных, делим обе части на (a*a+b*b).

Добавлено через 2 мин.
Только не из p*(a*a+b*b)>= 2*a*b*q+(a*a+b*b)*sqrt(a*a+b*b-q*q)
а из p*(a*a+b*b)>= 2*a*b*q+(a*a-b*b)*sqrt(a*a+b*b-q*q)

Автор: sheka 27.09.2010 5:07

TarasBer, что это за умное слово "симметризация" ? Нигде не могу его найти smile.gif
Интересует потому, что вроде в таком виде оно действительно симметрично, но правая часть будет ведь проще без ее, симметризации.

Автор: TarasBer 27.09.2010 21:30

Нет такого термина, это я для наглядности сказал.
Да, правая часть может быть записана как sqr(a2-b2), но в таком виде неравенство выглядит интереснее.