IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> Огненный Круг, Задача на Геометрию
сообщение
Сообщение #1


Бывалый
***

Группа: Пользователи
Сообщений: 231
Пол: Женский

Репутация: -  6  +


Важно:Сразу прошу вас не пишите готовую программу ,а только объясните сам алгоритм в кратце:
yes2.gif Это задача с онлайн :http://acm.timus.ru/problem.aspx?space=1&num=1490 yes2.gif
Лич Сандро проводит свои научные исследования в магии огня. Сандро стоит в центре огромного квадратного зала площадью 1000000 квадратных километров, сплошь замощённого квадратными каменными плитами со стороной один метр. По взмаху посоха вокруг Сандро возникает огненный круг радиуса R метров. Центр круга совпадает с центром зала и находится в месте соприкосновения 4-х плит. Сандро хочет посчитать, сколько плит будет испорчено огнем. Считается, что плита испорчена, если она имеет хотя бы две общие точки с кругом. На рисунке в качестве примера изображены плиты, испорченные огненным кругом радиуса 4:

Исходные данные
В единственной строке записано целое число R > 0 — радиус огненного круга. R не превосходит 10^5.
Результат
Выведите целое число — количество испорченных плит.
Примеры:
2-16
4-60

smile.gif

Сообщение отредактировано: Perfez -


Эскизы прикрепленных изображений
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


меркантильный
***

Группа: Пользователи
Сообщений: 161
Пол: Мужской

Репутация: -  6  +


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

program Setka;
uses graph;
const r=155;
var Gd, Gm, i: Integer;
begin
Gd := Detect; i:=0;
InitGraph(Gd, Gm, ' ');
setcolor(15);
while i<600 do
begin
i:=i+40;
Line(0+i,0,0+i,500); Line(0,0+i,920,0+i);
circle(320,240,r);
end;
OutTextXY(325, 245, '0,0');
OutTextXY(365, 245, '1'); OutTextXY(325, 205, '1');
readln;
end.


Затем пальцем по экрану-считать /шутка smile.gif /
Сделать то же, но не графически, а через формулы площадей...
(Кстати, напоминает задачу геометров 16в/кажется/ о квадратуре круга-
как построить круг,с помощью циркуля,карандаша и линейки,
по площади равный данному квадрату со стороной N./Задача о квадратуре круга
с пом.циркуля, кар. и линейки не решается
/)


--------------------
Смысл откроется тебе. Красками играя
Жизнь предстанет как поток без конца и края.


В этом мире порой разбиваютсямечты
Но чтобы он стал другой Вдруг в него приходишь ТЫ...

После странствий и скитаний настают другие времена.
Старая волна уходит и приходит новая волна.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Нужно пройтись по квадратам, проверяя, есть ли у них точки, находящиеся на расстоянии меньше R от центра. При этом можно учесть следующее..

Во-первых, достаточно пройтись по одному квадранту - например, x>0, y>0 - а потом домножить результат на 4.
По-хорошему, нужно было и квдрант поделить биссектрисой пополам, но это немного усложнит алгоритм (поскольку пришлось бы отдельно учитывать квадраты, лежащие на биссектрисе)..
Во-вторых, достаточно ограничится проверкой квадратов, которые лежат на расстоянии не более R от центра по каждой координате.
В третьих, достаточно проверять только одну точку каждого квадрата - а именно, левый нижний угол (если квадрант выбран, как сказано выше).

Таким образом, получаем двойной цикл (по x и по y) от 0 до R. Расстояние вычисляем по теореме Пифагора. Соотношение для проверки получается следующее:

Sqrt(x^2+y^2)<R

Но, учитывая, что квадратный корень может дать некоторую ошибку, я бы предпочел проверять сами квадраты:

x*x + y*y < R*R

Если это условие выполнено - круг испорчен, если нет - замена плитки не требуется.. smile.gif
Обрати внимание на строгое неравенство в условии! При нестрогом выполнении, может произойти "касание" в одной точке, что (по условию гарантии smile.gif) не является большим повреждением..
Не забудь полученное число умножить на 4 (либо првести циклы от -R до R)

2 Чужак:
Эта задача не имеет никакого отношения к квадратуре круга. Кстати, КК гораздо древнее XVI века - она занимала еще древних греков, насколько мне известно..


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Бывалый
***

Группа: Пользователи
Сообщений: 231
Пол: Женский

Репутация: -  6  +


огромное спасибо,Lapp. smile.gif но существует одна проблема взгляни на screen: wink.gif
Прикрепленное изображение

вот сам pas файл:
Прикрепленный файл  1490.pas ( 146 байт ) Кол-во скачиваний: 584


что делать?посоветуй что-нибудь может обратиться к первому алгоритму-пифагора? blink.gif wacko.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Perfez @ 28.02.2007 8:09) *

посоветуй что-нибудь

Я же сказал: используй вторую форму! с квадратами.. Она должна работать быстрее. При этом вычисли R^2 заранее.



Добавлено через 1 мин.
Кроме того, не вижу у тебя обнуления z перед циклом.

Добавлено через 2 мин.
То есть с перемножениями, извини. Хотя, скорее всего это все равно..

Но вынос R*R за оба цикла должен сработать. А вычисление x*x можно вынести за внутренний цикл, во внешний.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Бывалый
***

Группа: Пользователи
Сообщений: 231
Пол: Женский

Репутация: -  6  +


может ещё что-нибудь посоветуешь? smile.gif ...если не надоел я ещё
Прикрепленное изображение


Прикрепленный файл  1490.pas ( 176 байт ) Кол-во скачиваний: 555

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Сходил по ссылке, глянул. Ситуация серьезная.. smile.gif
Нужно менять алгоритм полностью.
Например, так..

1. Обнуляем z (счетчик плиток).
2. Обнуляем y
3. В х кладем R (координаты)
4. Делаем условный цикл: пока x^2+y^2>R^2 , уменьшаем х на 1 (если x<0 - выходим)
5. Увеличиваем z на x
6. Увеличиваем y на 1
7. Если y>R - выходим.
8. Переходим к 5

Это будет обход по контуру круга, начиная справа-снизу квадранта (четверти круга). Плитку суммируем горизонтальными полосами. Заметь, что у снова можно возводить в квадрат вне цикла.

Через минут 10-15..
Исправляю два пункта: 4 и 7

Сообщение отредактировано: Lapp -


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Цитата
может ещё что-нибудь посоветуешь?
А можно мне?
Смотри, что ты делаешь:
For x:=0 to r do
Begin

t:=Sqr(x);
For y:=0 to r do
If t+Sqr(y)<q then Inc(z);

End;

Берем бубен, и ...

For x:=0 to r do
Begin

t:=Sqr(x);
For y:=0 to r do
If t+Sqr(y)<q then Inc(z)
Else Break; { <--- Все равно дальше - бесполезная работа }

End;

... а время выполнения - экономит...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Бывалый
***

Группа: Пользователи
Сообщений: 231
Пол: Женский

Репутация: -  6  +


 
var
x,y,r:longint;
z,q,t:longint;
Begin
ReadLn®;
q:=Sqr®;
For x:=0 to r do
Begin
t:=Sqr(x);
For y:=0 to r do
If t+Sqr(y)<q then Inc(z)
Else Break;
End;
z:=z*4;
WriteLn(z);
End.


Не Volvo,и бубен не катит... no1.gif А жаль,мог бы легко отделаться... smile.gif
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Бывалый
***

Группа: Пользователи
Сообщений: 231
Пол: Женский

Репутация: -  6  +


Цитата(Lapp @ 28.02.2007 15:16) *

3. В х кладем R (координаты)

Обьясни пожалуйста,как понять? blink.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Perfez @ 28.02.2007 16:39) *

3. В х кладем R (координаты)
- Обьясни пожалуйста,как понять? blink.gif

Очень просто:
x:=R
Слово в скобках означает, что нововведенные переменные y и x - это координаты (типа пояснение)
smile.gif


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Бывалый
***

Группа: Пользователи
Сообщений: 231
Пол: Женский

Репутация: -  6  +


Цитата(Lapp @ 28.02.2007 15:16) *

1. Обнуляем z (счетчик плиток).
2. Обнуляем y
3. В х кладем R (координаты)
4. Делаем условный цикл: пока x^2+y^2>R^2 , уменьшаем х на 1 (если x<0 - выходим)
5. Увеличиваем z на x
6. Увеличиваем y на 1
7. Если y>R - выходим.
8. Переходим к 5

Все эти 8 пунктов в цикле или я не понимаю обнуление на что? blink.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Гость






Perfez, что-то там очень странное с тестами... Я пробовал делать так:

Цитата(Lapp)
4. Делаем условный цикл: пока x^2+y^2>R^2 , уменьшаем х на 1 (если x<0 - выходим)
5. Увеличиваем z на x
заменил на
Цитата
4. Устанавливаем X в [sqrt(R2 - Y2)]
4а. Условный цикл: пока x2+y2<R2 увеличиваем X на 1 ...
5. Увеличиваем z на x
Далее по алгоритму Lapp-а, программа летает, только проходит 9 тестов как положено, на 10-м выдает неправильный результат, хотя должно работать... Ничего не понимаю...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Perfez @ 28.02.2007 22:34) *

Все эти 8 пунктов в цикле или я не понимаю обнуление на что? blink.gif

Это полный алгоритм. Обнуление - это значит "присвоить ноль".
Пишу фрагмент программы (примерно)

z:=0;
x:=R;
R2:=R*R;
for y=R downto 0 begin
y2:=y*y;
while (x*x+y2<R2)and(x>0) do Dec(x);
Inc(z,x);
....


По ходу обнаружил ошибку - в п.8 переход не на 5, а на 4. Трудно уследить за нумерацией в такой записи.. Надеюсь, ты отслеживаешь смысл smile.gif.


Добавлено через 4 мин.
Выитание R^2-y^2 вне цикла - очень здравая идея smile.gif


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Бывалый
***

Группа: Пользователи
Сообщений: 231
Пол: Женский

Репутация: -  6  +


Цитата(Lapp @ 1.03.2007 0:18) *

z:=0;


Разве в Паскале,z автоматически не обнуляется?(Free Pascal) smile.gif

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Гость






Цитата
Разве в Паскале,z автоматически не обнуляется?
Я бы не стал на это надеяться... Лучше сделать самому, чем потом искать ошибку, которой нет...

Кстати, то, что я написал выше я поправил - проблема была только в том, что по умолчанию Sqrt работает с Double, а мне надо было Extended... Доп. переменная решила проблему - все тесты пройдены...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Бывалый
***

Группа: Пользователи
Сообщений: 231
Пол: Женский

Репутация: -  6  +


Так,так...ну не понимаю я это алгоритм... smile.gif
Цитата

6. Увеличиваем y на 1

Цитата

for y=R downto 0 begin

Ну нельзя же изменять значение у в цикле,разве я не прав?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Perfez @ 1.03.2007 0:07) *

Так,так...ну не понимаю я это алгоритм... smile.gif
Ну нельзя же изменять значение у в цикле,разве я не прав?

Нельзя, верно. Но и не надо! smile.gif
Я просто перенес изменение у в сам цикл.

Погоди, сейчас я нарисую картинку. Тогда поймешь..
Заходи минут через 15


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Как обычно - снова обнаружил у себя ошибку.. Алгоритм правильный, ошибка в фрагменте кода. Почему-то я цикл по y перевернул - странно.. Цикл должен быть от 0 до R, конечно.


Вот, смотри, наглядно на рисунке.
Начинаем справа внизу.
Красные стрелки - цикл по y, зеленые - внутренний цикл с уменьшением x.
Желтые клетки - те на которых останавливается внутренний цикл.
Голубые - те, которые он проходит.
Суммируем те клетки, что слева от желтых (включая их тоже).

Прикрепленное изображение


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Бывалый
***

Группа: Пользователи
Сообщений: 231
Пол: Женский

Репутация: -  6  +


Я наконец-таки понял алгоритм smile.gif good.gif и смастерил-что-то вроде этого?Прикрепленный файл  1490.pas ( 200 байт ) Кол-во скачиваний: 607
если да то он выводит неправильный результат... no1.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 23.12.2024 20:18
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name