1 | |
Найти площадь крупнейшего сплошного прямоугольника суши29.11.2012, 14:01. Показов 3014. Ответов 19
Наибольшая площадь
Территория состоит из квадратиков суши (обозначены единичками) и воды (обозначены ноликами). Найти площадь крупнейшего сплошного прямоугольника суши. В файле данных "land.txt" в первой ленте размеры территории. Далее - карта территории. Пример входных даих 7 8 01110111 11110111 11111101 11111101 01111111 10111111 11011111 ответ 16 Добавлено через 19 часов 30 минут upupupup
0
|
29.11.2012, 14:01 | |
Ответы с готовыми решениями:
19
Известны координаты вершин прямоугольника ABCD , A(x1,y1), B(x2,y2), C(x3,y3). Найти площадь и периметр прямоугольника. Известны вершины прямоугольника. Найти площадь и периметр прямоугольника Найти площадь прямоугольника Найти площадь прямоугольника |
Пес войны
111 / 88 / 22
Регистрация: 23.02.2012
Сообщений: 653
|
|
29.11.2012, 15:52 | 2 |
хоть убей, не вижу прямоугольника из 16 единиц(
0
|
Почетный модератор
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
|
|
29.11.2012, 16:13 | 3 |
NeonLost,
01110111 11110111 11111101 11111101 01111111 10111111 11011111
1
|
Почетный модератор
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
|
|
04.12.2012, 10:56 | 4 |
Три дня думал над алгоритмом, и что-то ничего не придумывается.
Ну давай тогда рассуждать. Смотри. Самое первое что приходит на ум это огромным количеством вложенных циклов замерить расстояние от каждой единицы до нуля (или края области) во всех четырех направлениях. Таким образом мы узнаем какую-то величину, назовем ее, к примеру, вес единицы. Посмотрим что это нам даст. Берем и проходим перебором по всем элементам области (на рисунке красный квадрат). От каждого элемента по четыре цикла (вверх, вниз, влево, вправо). Таким образом получаем для каждой единицы четверку значений. Для текущего элемента (на картинке): Верх : 2; Низ: 3; Лево: 2; Право: 3; Составив такие четверки для каждого элемента получим (для наглядности) таблицу: Слева таблица непосредственно четверок (в порядке: лево, право, верх, низ), а справа просуммированные значения четверок. В принципе существует закономерность между величиной суммы и площадью, занимаемой прямоугольником: чем больше значение суммы, тем в более обширный прямоугольник входит единица. Но четкого определения нет. Далее, если следовать той же логике, нужно каким-то образом усреднить значения сумм четверок, чтобы в идеале все единицы наибольшего прямоугольника имели одинаковый меж собой и наибольший меж не входящими в прямоугольник элементами. Тогда все станет просто. Но вот как сделать это просто? Я вот думал в сторону если запустить от каждого элемента еще по четыре цикла (так же вверх, вниз, влево, вправо) и на каждой итерации еще по два цикла под девяносто градусов от текущего направления. На картинке слева представлен один только проход вниз. Синие цифры и круглые стрелки - итерации прохода вниз. (нулевая итерация - от красного квадрата) Плоские стрелки это дополнительные проходы влево и вправо на каждой итерации спуска вниз. Смысл: Рассмотрим вторую итерацию (кружок с цифрой 2) Движемся от него вправо и проверяем текущее значение со значением "право" из четверки предыдущего элемента. Видим, что на четвертом шаге вправо мы превысили значение вправо для предыдущего элемента. На этом проход вправо прерываем и текущему элементу (кружок с 2) присваиваем в его четверку в значение "право"текущий результат цикла минус один. По сути то же самое значение, что и у элемента выше. При проходе же влево (то есть когда у нас значения становятся постоянно меньше текущего) надо найти самое минимальное значение среди всех и всей вертикали (можно обратным циклом) присвоить его. Вот что-то как-то так. Что из этого получится одному богу известно. Но можешь попробовать. Была еще одна мысль в другую сторону, другой алгоритм: находить нули, от них во все стороны проводить линии, которые будут образовывать прямоугольники, определять их углы и замерять площадь. Но как это реализовать я еще не придумал. Можно пока обсудить первый вариант. Надеюсь хоть как-то помог.
2
|
425 / 390 / 113
Регистрация: 21.09.2012
Сообщений: 913
|
||||||
04.12.2012, 13:18 | 5 | |||||
неправильная у меня программа. сейчас проверил и что-то не сходится.
1
|
Почетный модератор
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
|
|
04.12.2012, 13:40 | 6 |
1
|
425 / 390 / 113
Регистрация: 21.09.2012
Сообщений: 913
|
|
04.12.2012, 13:55 | 7 |
вообщем искал первый элемент массива который равен нулю по Х и по У справа и внизу от текущей клетки и потом искал площадь. вообще направильно работает. хотя первый раз результат получился правильным - 16
0
|
Почетный модератор
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
|
|
04.12.2012, 14:06 | 8 |
Это вот второй как раз метод, который я думал.
Только. Надо как только нашел первый ноль (первый угол прямоугольника) останавливать цикл и искать второй ноль, который будет дальше (по проходу) (второй угол). И потом до него мерить прямоугольник. Как только до всех вторых углов промерено, сдвинуть на следующий ноль первый угол. Но так не пойдет. Так как углы прямоугольника могут находиться и не в самом нуле.
1
|
Почетный модератор
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
|
|
04.12.2012, 14:48 | 9 |
Ах-ха-ха-ха-ха! (гомерический смех) Ну что за тупизм.
Придумал. Сначала подумалось, что раз такая пьянка, то почему бы и не перебирать вообще ВСЕ прямоугольники, и смотреть заполнены ли они единицами. Почему бы и нет. Так меньше проходов получится. по сути это двойной проход по всей площади: сначала один угол стоит, а второй пробегает все значения, потом первый угол сдвигается на один элемент, второй при этом опять пробегает все значения. Это два цикла. А третий, самый вложенный уже проверяет выбранную площадь от одного угла до другого на полное заполнение единицами. Фигня! Круче способ: 1) Один главный проход по всем элементам всей области слева направо, сверху вниз. 2) Если попадается единица, от нее (Mas[i,j]) вправо отсчитываем до первого встретившегося нуля (или края области). Запоминаем (x). От нее же отсчитываем вниз до нуля (края). Запоминаем (y). 3) Двойной цикл от j до y и от i до x: перебираем область. Если нули не встречаются, тогда запоминаем площадь и координаты сектора. Если встречается ноль, то сравниваем что меньше текущее значение от j до y или от i до x (грубо говоря мы по строке дальше сдвинулись вправо или по столбцу опустились). Соответственно запоминаем наибольшее значение для площади. 4) Сравниваем с предыдущим наибольшим значением. Красный квадрат - текущий элемент. Красные стрелки - проход вправо и вниз. Синий квадрат - общая область для этого элемента. Зеленый овал - полученная область. Зеленые стрелки - обход выбранной области.
2
|
425 / 390 / 113
Регистрация: 21.09.2012
Сообщений: 913
|
|
04.12.2012, 15:35 | 10 |
SatanaXIII, Осталось программу написать
0
|
425 / 390 / 113
Регистрация: 21.09.2012
Сообщений: 913
|
|
05.12.2012, 19:24 | 12 |
Если до завтра никто не решит то утром тогда посмотрю. Но ничего не обещаю. Задача уж больно сложная
0
|
05.12.2012, 20:43 | 13 | |||||
*Просматриваем все элементы в цикле. *Если встречаем 1, то считаем единицы справа от нее до нуля (находим горизонтальную строчку единиц). *Переходим на строку ниже и проверяем соответствующий диапазон столбцов, если встречаем 0 - прекращаем подсчет, иначе проверяем следующую строку (в цикле). Особо не тестировал)
0
|
Почетный модератор
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
|
||||||
07.12.2012, 11:54 | 14 | |||||
Сообщение было отмечено mik-a-el как решение
Решение
Исполняю.
Алгоритм: 1) Двойной цикл (i, j) - перебор всех элементов области. 2) От каждого [i][j]-го элемента два цикла - проходы вправо и вниз. До нуля или края области. Получив два значения смещения (ShiftDown и ShiftRight) высчитывается площадь, допустимая для данного прямоугольника. Если она оказалась больше предыдущей запомненной, то смотрим вся ли они состоит из единиц (то есть не нулей), есть ли в ней нули. Вычисление площади на этом этапе ускоряет перебор так как нам не надо искать нули для прямоугольника, который даже если и заполнен только единицами, все равно меньше по площади, чем предыдущее найденное значение. Нам не важно на этом этапе что содержится в самом прямоугольнике (на рисунке х х х х х). 3) Для этого проходим эту область сначала построчно потом постолбцово. В обоих циклах упремся в один и тот же ноль, если он есть, но только с разных сторон. Если перебираем построчно, то, найдя ноль, уменьшаем счетчик строк (countY-1) Во втором цикле соответственно счетчик столбцов (countX-1). Смотрим что у нас получилось больше. Ту площадь и запоминаем. Так же запоминаем координаты левого верхнего и правого нижнего углов прямоугольника. Если ноль не встретился, то запоминаем наибольшую площадь для этого прямоугольника: (LastAngleX-FirstAngleX)+1)*((LastAngleY-FirstAngleY)+1 Прибавление единицы здесь нужно из-за того, что размерность массива начинается с нуля. Чтобы при умножении не получить нулевую площадь заместо площади шириной в один столбец (строку). В итоге имеем координаты прямоугольника и его площадь.
2
|
BRcr
|
01.11.2014, 13:26
#15
|
Не по теме: Неоцененный труд, однако.:good:
0
|
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
|
||||||
02.11.2014, 23:40 | 16 | |||||
SatanaXIII, а с такими данными выдает 16 вместо 20
0
|
221 / 166 / 47
Регистрация: 17.07.2012
Сообщений: 587
|
|
03.11.2014, 01:20 | 17 |
1
|
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
|
|
03.11.2014, 13:22 | 18 |
SlavaSSU, неплохой алготитм.
Для интереса сравнил время подсчета со своим, приведенным выше для матрицы из 30 млн элементов (5000x6000). Мой сделал за 2с, ваш - за 12с, результаты совпали. Но поскольку мой считает в лоб - O(n2m2), то для огромных матриц ваш, видимо, будет быстрее. Хотя и в моем остается немалый простор для оптимизации даже в рамках текущего алгоритма. Добавлено через 3 часа 36 минут Неполенился проверить для других соотношений нулей и единиц. Прошлый тест проводился для 1:1 Начиная с соотношения 7:1 ваша программа уверенно вырывается вперёд. Ответы остаются одинаковыми, что наталкивает на мысль, что обе программы считают правильно.
0
|
Почетный модератор
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
|
|
10.11.2014, 08:55 | 19 |
0
|
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
|
|
10.11.2014, 23:41 | 20 |
Признаю свою ошибку, я просмотрел другой алгоритм (из поста #13) и это он выдает 16 вместо 20.
Ваш на массиве 2000x4000 выдал ошибку сегментирования. Если не пропал интерес, скорректируйте код, чтобы читал входные данные, как в условии задачи. Я прогоню на эффективность.
0
|
10.11.2014, 23:41 | |
10.11.2014, 23:41 | |
Помогаю со студенческими работами здесь
20
Найти площадь прямоугольника Найти площадь прямоугольника Найти периметр и площадь прямоугольника Найти площадь и периметр прямоугольника Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |