Имя: Пароль:
1C
1С v8
Задача про лабиринт
0 k504sa
 
12.02.17
03:22
Доброго времени суток всем!
Имеется задача, у кого какие мысли по ее решению в 1С?

// ЗАДАЧА:
// Определить количество замкнутых несвязанных между собою пустот (дырок) в лабиринте размера N*M // 1 <= N <= 200, 1 <= M <= 200 // // ВХОД:
// Текстовый файл, содержащий массив N*M в виде строк (т.е. N строк, каждая длиной M символов) // Символы: '.' - пусто '#' - занято (стенка лабиринта) // // НУЖНО ПОЛУЧИТЬ:
// Число замкнутых несвязанных между собою пустот (дырок) в переданном во входном файле лабиринте.
//
// ПОЯСНЕНИЕ:
// Пустота считается несвязанной с другими, если у неё нет смежных с другой пустотой клеток // по горизонтали или вертикали. Т.е. из одной пустоты нельзя перейти в другую пустоту // двигаясь по любой траектории и делая шаги по горизонтали и/или вертикали.
//
// Важно! Необходимо учитывать только пустоты, замкнутые стенами лабиринта со всех сторон!
//
// ВЫХОД:
// Вывести исходный файл и под ним - найденное число пустот.
// Или вывести сообщение об ошибке, если входной файл некорректен.
//
// ПОЯСНЯЮЩИЕ ПРИМЕРЫ:
//
// ###...###. ###...###.
// #.##.###.. #1##.###..
// ####...... => ####......
// ......#### ......####
// .###.#...# .###.#222#
// .....##### .....#####
//
// В этом примере у нас 2 (ДВЕ) дырки замкнутые в стенах лабиринта (помечены цифрами '1' и '2').
//
// ########## ##########
// #..##..### #11##22###
// ###.###..# => ###3###44#
// #..##.#..# #66##5#44#
// ########## ##########
//
// В этом примере у нас 6 (ШЕСТЬ) дырок.
//
// #####..... #####.....
// ....#..... ....#.....
// #####.###. => #####.###.
// .....#...# .....#111#
// ......###. ......###.
//
// В этом примере у нас 1 (ОДНА) дырка. Остальные пустоты, хотя из них и нельзя перейти из одной в другую, // не являются дырками, т.к. не замкнуты стенами лабиринта со всех сторон!
1 Лодырь
 
12.02.17
08:04
Мысль, что задача элементарна, решается быстро и не имеет практического смысла.
2 Лодырь
 
12.02.17
08:05
У тебя даже в примерах методика решения приведена, по сути. Надо только закодить.
3 b_ru
 
12.02.17
08:07
Модифицированный волновой алгоритм. Находим пустую ячейку, красим ее, затем красим всех соседей, пока есть чего красить. После этого ищем следующую пустую (и некрашенную) и повторяем. Когда пустых больше нет, проверяем сколько использовано цветов - это и есть ответ.
4 k504sa
 
12.02.17
11:05
(3) За идею про волновой алгоритм спасибо. Попробую реализовать.
5 Asirius
 
12.02.17
11:38
тут на 15 минуть кодить...держи

Функция ОпределитьКоличествоПустот(Лабиринт)

    ТекущийЦвет = 0;
    НовыйЛабиринт = ДобавитьГраницуКЛабиринту(Лабиринт); //Границу  и все что с ней рядом красим 1 цветом

    Для Каждло Клетка Из НовыйЛабиринт Цикл
        Если КлеткаОкрашенаИлиСтенка(Клетка) Тогда
            Продолжить;
        КонецЕсли;

        ТекущийЦвет = ТекущийЦвет +1;
        ПокраситьКлетку(Клетка,ТекущийЦвет);

        Волна = Новый Массив;
        Волна.Добавить(Клетка);

        Пока Волна.Количество()>0 Цикл
            ТекущаяВолнна = Волна;
            Волна = Новый Массив;
            Для Каждого КлеткаВолны из ТекущаяВолнна  Цикл
                Для Каждого СоседняяКлетка из СоседиКлетки(КлеткаВолны) Цикл
                    Если Не КлеткаОкрашенаИлиСтенка(СоседняяКлетка) Тогда
                        ПокраситьКлетку(СоседняяКлетка,ТекущийЦвет);
                        Волна.Добавить(СоседняяКлетка);
                    КонецЕсли;
                КонецЦикла;         
            КонецЦикла;
        КонецЦикла;            
    КонецЦикла;
    Возврат ТекущийЦвет-1;
КонецФункции;
6 Asirius
 
12.02.17
11:50
Если задачу модифицировать так, что допустим не обход лабиринта, а обход шахматным конем на частично занятой шахматной доске (посчитать, сколько изолированных областей для коня), то у хомячков начинает мозг вскипать..

А по сути алгоритм будет тотже, надо просто функцию переопределить СоседиКлетки(Клетка)
7 k504sa
 
12.02.17
12:08
(5) Большое спасибо) вечерком поразбираюсь.