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

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

Форум «Всё о Паскале» _ Задачи _ Диагонали многоугольника

Автор: RathaR 5.07.2009 20:40

Задача следующая:
В выпуклом многоугольнике который имеет N вершин провели все диагонали, никакие три из них не пересекаются в одной точке. Найти количество частей на которые эти диагонали его розделили.
Задача в числе простых но в голову ничего не лезет...
Подскажите с помощью чего её можна решить?
Ведь зависимость между кол-вом вершин и числом елементов на которые его разбивают диагонали не линейная... Следовательно может быть здесь нужно задействовать рекурсию? или считать пересечения диагоналей? направте на путь истинный rolleyes.gif

Автор: Krjuger 5.07.2009 22:07

Товарищ,у вас явно не совсем корректное задание.

Цитата

провели все диагонали, никакие три из них не пересекаются в одной точке.

Эти две вещи явно противоречат друг другу.как я понимаю вам надо найти максимальное количесво диагоналей,которые удовлетворяют вашему условию.
Цитата

Следовательно может быть здесь нужно задействовать рекурсию

Абсолютно не следовательно.При чем тут рекурсия?Вы для начала итеративно сдетайте,а уж потом рекурсивно.
Цитата

или считать пересечения диагоналей

Ну вам наоборон надо делать.
Цитата

кол-вом вершин и числом елементов на которые его разбивают диагонали не линейная

Вообще то она линейная....число элементов равно N-1 для N вершин.

для начала задумайся над тем,как ты будеш определять пересекаются ли 3 диагонали в одной точке......

Я могу предложить считать количество смежных фигут, для которых эта точка считается вершиной,например при пересечении двух диагоналей получится 4 фигуры,а при пересечении 3 прямых уже 6 фигур.

Автор: volvo 5.07.2009 22:13

Цитата
Эти две вещи явно противоречат друг другу
Это чем же, интересно?

Добавлено через 40 сек.
Цитата
для начала задумайся над тем,как ты будеш определять пересекаются ли 3 диагонали в одной точке......
Они ПО УСЛОВИЮ не пересекаются, о чем тут задумываться?

Автор: RathaR 5.07.2009 22:47

Цитата(Krjuger @ 5.07.2009 18:07) *

Вообще то она линейная....число элементов равно N-1 для N вершин.

эм...а как ето возможно? диагонали только с одной вершини розбивают фигуру на N-2 треугольника, тоесть, елемента.
С подсчетом смежных фигур, для которых вершина многоугольника тоже является вершиной ето конечно идея, но как тогда считать те куски которые остались внутри многоугольника.
У меня по поводу етой задачи других мыслей нет... насторажевает то что она самая лёгкая, а пару задачек посложней я решил...

Автор: Krjuger 5.07.2009 23:26

Видно,Vlovo,мы условие по разному поняли.Ладно видимо в первый раз я не правильно понял.

Цитата

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

А что тебе мешает для других,вот смотри для каждой вершини многоугольника n-2(тут я описался),то что у тебя не пересекаются никакие 3 говорит о том, что у тебя могут пересекаться две диагонали, тогда они тоже образуют точку, причем то что только две диагонали дает тебе право говорить что у тебя будут только 4 фигуры,для которых эта новая точка будет вершиной,и по сути тебе останется только сосчитать их количество и вычесть их повторения.

Автор: Lapp 6.07.2009 14:39

Цитата(RathaR @ 5.07.2009 17:40) *
Задача в числе простых но в голову ничего не лезет...
RathaR, давай не будем записывать задачу в "число простых" по крайней мере до тех пор, пока тебе хоть что-нибудь "в голову не влезет". А то как-то мне, считающему ее не самой простой, даже как-то странно помогать тебе, для которого она "в числе простых".

Но я все же попробую.. Но сначала уточни. Правильно я понимаю, что тебе дано конкретное число N, а конкретные значения вершин не даны? То есть их нужно выбрать произвольно, но при наложенном условии на пересечение диагоналей. При этом программа должна выдавать ответ как функцию числа N - так? Если так, то несколько неясно, кем доказана независимость этой функции от вида многоугольника (то есть от конкретных значений вершин)?

И вообще, задача сильно смахивает на чистую математику. Хотя, вполне возможно, что формула не такая простая, и тогда программное решение (возможно, и с рекурсией) вполне уместно.. Но, если так (то есть, если программа не есть просто вычисление по известной формуле, а нужно моделировать процесс разбиения и подсчитывать число частей), то я никак не склонен называть такую программу "простой".

P.S.
А Большая теорема Ферма для тебя случайно не "в числе простых"? smile.gif

Добавлено через 4 мин.
Цитата(RathaR @ 5.07.2009 19:47) *
насторажевает то что она самая лёгкая, а пару задачек посложней я решил...
Все же открой секрет, как ты разбиваешь задачи на "совсем легкие" и "послежнее"? Я балдею с твоих заявлений о простоте.. blink.gif

Автор: RathaR 6.07.2009 15:06

Цитата(Lapp @ 6.07.2009 10:39) *

RathaR, давай не будем записывать задачу в "число простых" по крайней мере до тех пор, пока тебе хоть что-нибудь "в голову не влезет". А то как-то мне, считающему ее не самой простой, даже как-то странно помогать тебе, для которого она "в числе простых".


Назвая её простой я не имел в виду то что она лично для меня меня простая, это задача с олимпиады этого года и из 4 заданий из которых я решил 2 и 3 (за которые дают больше балов) она первая, и за неё дают балов меньше остальных, но вот с ней я так и не разобрался...

По поводу условия: про сам многоугольник неизвестно ничего, сказно только что он выпуклый и никакие три ез его диагоналей не пересекаються в одной точке, дано лиш число N - кол-во вершин...

Про рекурсивную функцию я говорил потому что так и несмог найти зависимости между кол-вом вершин и кол-вом частей на которые диагонали розбивают фигуру.

Автор: Lapp 6.07.2009 15:17

Цитата(RathaR @ 6.07.2009 12:06) *
Назвая её простой я не имел в виду то что она лично для меня меня простая,
На мой взгляд, единственный способ доказать, что "лично для тебя она простая" - решить. Пока не решишь - по крайней мере "лично для тебя" она останется сложной. Хотя, количество баллов - это аргумент, согласен. Но только не "лично для тебя".

Так, кое-что начинает проясняться. Еще один вопрос: нужно подсчитать количество цельных частей, или, например, два смежных треугольника тоже составляют фигуру, которую нужно учитывать? Например, какой


Добавлено через 1 мин.
извиняюсь, что-то снова нажал случайно, и мессадж уехал недописанным.

... ответ будет для четырехугольника - 4?

Добавлено через 5 мин.
Если можно, приведи условие дословно, плз.

Автор: RathaR 6.07.2009 15:41

Цитата(Lapp @ 6.07.2009 11:17) *


... ответ будет для четырехугольника - 4?


Да, для четырехугольника 4.

Цитата(Lapp @ 6.07.2009 11:17) *

Если можно, приведи условие дословно, плз.

Условие на украинском языке...

Автор: Lapp 6.07.2009 16:50

Цитата(RathaR @ 6.07.2009 12:41) *
Условие на украинском языке...
Ничего, я попробую разобраться. Приведи, если не в лом.

Автор: RathaR 6.07.2009 17:12

Задача 1. Діагоналі.
Умова. У випуклому багатокутнику, що має N вершин провели всі діагоналі. Причому ніякі три з них не перетинаються в одній точці. В результаті багатокутник був розділений діагоналями на M частин.
Завдання: написати програму DIAGONAL яка знайде число M, тобто, на скільки частин був розділений многокутник діагоналями.
Вхідний текстовий файл містить у єдиному рядку ціле число N - кіллькість вершин (1<N<1000).
Вихідний текстовий файл містить єдине ціле число - кількість частин на які діагоналі розбивають багатокутник.

Автор: Гость 7.07.2009 9:06

Вот:

var
n,i,j,p: integer;

begin
repeat
Write('n = ');
ReadLn(n);
if n=0 then Exit;
p:=0;
for i:=1 to n do for j:=i+1 to n-1 do p:=p+(n-j)*(j-i-1)+1;
WriteLn('total parts: ',p)
until false
end.

Спасибо за задачку, полезно иногда прочистить мозги smile.gif.
Но легкой я бы ее все же не назвал. Пришлось сесть и потратить порядка часа чистого времени. Хотя решение явно недлинное. Наверное, почаще надо такими вещами заниматься)).

Кстати, возможно, что можно и короче. Возможно, что можно и вообще без циклов (изначально у меня их было аж четыре)).

Автор: Lapp 7.07.2009 9:08

Под маской гостя скрывался (ненарочно) я. Извиняюсь))

Добавлено через 3 мин.
И еще: украинский текст меня очень порадовал)). Особенно "багатокутник" smile.gif

Автор: RathaR 7.07.2009 12:12

Цитата(Гость @ 7.07.2009 5:06) *

Вот:

готовый код это канешно очень хорошо, и за это вам большое спасибо rolleyes.gif но только целью моей было скорее понять её, чем получить готовую,а этого решения я если чесно часик просидел, и непонял. Хотелось бы алгоритм услышать, т.к. так и не понял, зачем во вложеном цыкле параметр и конечный параметр приближены друг к другу, и почему именно
 p:=p+(n-j)*(j-i-1)+1;


Хотя решение с одним вложеным цыклом конечно немного удивило smile.gif

Автор: Lapp 7.07.2009 12:22

Цитата(RathaR @ 7.07.2009 9:12) *
но только целью моей было скорее понять её, чем получить готовую,
...
Хотя решение с одним вложеным цыклом конечно немного удивило

Нет проблем, я еще пока, кажется, помню, как решал)). Сейчас напишу. Только вот рисунок сделаю..

А что именно удивило: что цикл - или что мало циклов?

Автор: RathaR 7.07.2009 12:31

Цитата(Lapp @ 7.07.2009 8:22) *

А что именно удивило: что цикл - или что мало циклов?

удивила простота реализации... никаких функций, процедур, деревьев, рекурсии и т.д. , тоесть это посилу написать человеку который неособо то знаком с паскалем, лиш бы только алгоритм понимал, и с логикой проблем не имел ...

Автор: Lapp 7.07.2009 13:08

Пока писал и рисовал объяснение, у меня появилось сомнение в том, что задача решена верно sad.gif.
Программа дает верные результаты для N = 1, 2, 3, 4, 5, 6, 7. А дальше я не проверял. Если кому не в лом, проверьте плз. Одно из двух: либо я действительно забыл свои рассуждения, либо увы.. Но сейчас башка уже не варит - поздно. Я додумаю завтра, если вы не возражаете.. smile.gif

Автор: RathaR 7.07.2009 13:27

Цитата(Lapp @ 7.07.2009 9:08) *

Пока писал и рисовал объяснение, у меня появилось сомнение в том, что задача решена верно sad.gif.
Программа дает верные результаты для N = 1, 2, 3, 4, 5, 6, 7. А дальше я не проверял. Если кому не в лом, проверьте плз. Одно из двух: либо я действительно забыл свои рассуждения, либо увы.. Но сейчас башка уже не варит - поздно. Я додумаю завтра, если вы не возражаете.. smile.gif

я никак абсолютно не возражаю, и не хочу напрягать мыслительный процесс, а по поводу результатов:
Хєх, вот только что прикинул, если поменять переменную p на LongInt то получим результат гдето до N= 450 а дельше число фрагментов больше 2 000 000 000, а в условии сказано N до 1000, такчто в идеале прийдётся еще работать со строками чтоб получить полный результат %)

Автор: volvo 7.07.2009 13:58

Цитата
можно и вообще без циклов
yes2.gif
WriteLn(trunc((n-1)*(n-2)*(sqr(n)-3*n+12) / 24));


Цитата
такчто в идеале прийдётся еще работать со строками чтоб получить полный результат %)
Про тип Comp (который может хранить значения от -263 + 1 до 263 - 1) не забывай. Тебе емкости этого типа - за глаза хватит, не надо придумывать самому себе проблемы на ровном месте.

Автор: RathaR 7.07.2009 21:06

Цитата(volvo @ 7.07.2009 9:58) *

Про тип Comp (который может хранить значения от -263 + 1 до 263 - 1) не забывай. Тебе емкости этого типа - за глаза хватит, не надо придумывать самому себе проблемы на ровном месте.

проверил... хватило rolleyes.gif только всерамно решения невкурил...

Автор: Lapp 8.07.2009 8:27

Цитата(volvo @ 7.07.2009 10:58) *

yes2.gif
WriteLn(trunc((n-1)*(n-2)*(sqr(n)-3*n+12) / 24));
Класс good.gif

RathaR, основная идея моего решения была в том, чтобы смоделировать процесс проведения диагоналей.
Занумеруем вершины многоугольника по порядку (важно, что по порядку). Теперь будем проводить диагонали. Каждая диагональ добавляет к существующей разбивке столько частей, на сколько её делят в настоящий момент (то есть сразу после проведения) другие диагонали. Например, в самом начале первая диагональ добавляет 1 часть к уже существующей 1 части (целый багатокутник), тем самым делая полное число частей равным 2. Вторая диагональ (например, в квадрате), имеющая 1 пересечение (то есть поделенная сама на 2 части) прибавляет 2 части, доводя полное число частей до 4. Можно организовать "проведение диагоналей" с подсчетом точек пересечения. Делаем так..

Проводим диагональ от вершины с номером А к вершине с номером В. Она может пересечь только те диагонали, одна вершина которых (назовем одну из них XY) лежит между А и В (то есть A<X<B), а вторая - вне этой дуги (Y<A or B<Y). Затем, чтобы получить число частей, нужно число пересечений увеличить на 1. Вот и вся идея. Еще раз обращаю внимание, что пересекать нужно только с уже проведенными диагоналями. Выяснить, какие диагонали уже проведены можно, используя порядок проведения. Сначала у меня была идея запоминать это в матрице NxN, но такая матрица слишком велика (по крайней мере для ТР), так что я оставил эту идею (оно и к лучшему)).

В процессе программирования алгоритм претерпел некоторые не меняющие смысла изменения, так что не вполне отражает суть построения.

А как вывести формулу, приведенную volvo, лучше спросить у него самого smile.gif.

Ну что, RathaR - ты все еще считаешь эту задачу легкой? smile.gif

Автор: RathaR 8.07.2009 9:55

Цитата(Lapp @ 8.07.2009 4:27) *

Ну что, RathaR - ты все еще считаешь эту задачу легкой? smile.gif

Я - уже нет mega_chok.gif , а вот организаторы олимпиады наверное всёже считают, раз дают за неё 15 баллов из 400... чем собственно и вводят в заблуждение учасников smile.gif
Еще раз спасибо за объяснение, сам бы вжизни не справился good.gif

Автор: Lapp 8.07.2009 10:22

Цитата(RathaR @ 8.07.2009 6:55) *
организаторы олимпиады наверное всёже считают, раз дают за неё 15 баллов из 400...
Возможно, они считают эту формулу известной. Но это мне в высшей степени странно.. Я погуглил немного (правда, совсем немного), но не нашел. Интересно, какой способ использовал volvo. Может, все и не так страшно, как я это представил smile.gif.

Автор: RathaR 8.07.2009 10:34

Цитата(Lapp @ 8.07.2009 6:22) *

Возможно, они считают эту формулу известной. Но это мне в высшей степени странно.. Я погуглил немного (правда, совсем немного), но не нашел. Интересно, какой способ использовал volvo. Может, все и не так страшно, как я это представил smile.gif.

Будь я 9 класником который впервые приехал на олимпиаду, и учитывая то, что задания у всех класов одинаковы, я бы с самого начала был бы настроен на то, чтоб попробовать решить первые 2 тоесть самые лёгкие задачи, и убить всё время именно на них, дабы получить хоть какието балы, а не плодить недоделлки по сложным задачам, а увидав бы такие задачи по 15 балов, я бы и дальше смотреть не стал, а розвернулся бы и просто ушол, при том что на математике показываю хорошые показатели, а геометрия мой конёк smile.gif
То как это трактовать? Как желание организаторов повысить уровень знаний молодёжи, или просто решили забить на 9, да и на 10 класс тоже, мол пусть учатся а в 11 класе будут готовы ко всему...

Автор: volvo 8.07.2009 14:56

Цитата
Интересно, какой способ использовал volvo
Использовалась известная формула (известная мне по крайней мере), согласно которой диагонали выпуклого многоугольника, никакие три из которых не пересекаются в одной точке, делят полигон на C2n-1 + C4n частей.

Ну, а упрощение выражения - это дело техники.

P.S. Кстати, на MathWorld-е я таки нашел эту формулу и результат упрощения (правда уже сегодня, после того, как вчера сделал это самостоятельно smile.gif ). Но это даже лучше, лишний раз пошевелить извилинами и вспомнить что-то (даже если не выводить) - тоже полезно...

Автор: Lapp 8.07.2009 15:16

Цитата(volvo @ 8.07.2009 11:56) *
это даже лучше, лишний раз пошевелить извилинами и вспомнить что-то (даже если не выводить) - тоже полезно...
Эт'конечно. Но помнить формулы (или хотя бы их существование) безусловно не вредно)).

Автор: s13 12.10.2013 20:25

а что если добавим условие что мы вводим и количество проведенных диагоналей в многоугольнике. как в таком случае код изменится?