Матч
397, Сортирующая игра (SortingGame)
Дивизион 2,
Уровень 2; Дивизион 1, Уровень 1
В Сортирующей Игре изначально задана
перестановка чисел от 1 до n
включительно. За один ход можно выбрать любые k последовательно стоящих чисел и развернуть их. Найти наименьшее
количество ходов, за которое можно отсортировать все числа в порядке
возрастания.
Класс: SortingGame
Метод: int
fewestMoves(vector<int> board, int k)
Ограничения: board содержит от 2 до 8 элементов, board
содержит перестановку чисел от 1 до n, где n – количество элементов в
board, 2 £ k £ n.
Вход. Массив board, содержащий перестановку чисел от 1 до n.
Выход. Наименьшее количество ходов, за которое можно отсортировать
числа. Если сортировка невозможна, то вернуть -1.
Пример входа
board |
k |
{1,2,3} |
3 |
{3,2,1} |
3 |
{7,2,1,6,8,4,3,5} |
4 |
{3,2,4,1,5} |
4 |
Пример выхода
0
1
7
-1
РЕШЕНИЕ
поиск в ширину
Задачу будем решать при помощи
поиска в ширину. Исходную перестановку, заданную в массиве board, заносим в
очередь поиска в ширину. После извлечения перестановки из очереди будем перебирать
в ней все возможные k последовательно
стоящих чисел, обращать их и класть в очередь. Отображение m хранит расстояние
от исходной перестановки до отсортированной.
ПРОГРАММА
#include <cstdio>
#include <vector>
#include <deque>
#include <map>
#include <algorithm>
using namespace std;
deque<vector<int> > q;
map<vector<int>,int> m;
class SortingGame
{
public:
int fewestMoves(vector<int>
board, int k)
{
vector<int> pos, p, Sorted;
int i, n = (int)board.size();
for(i = 1; i <= n; i++)
Sorted.push_back(i);
q.push_back(board);
while(!q.empty())
{
pos = q[0];q.pop_front();
if (pos == Sorted) return m[pos];
for(i = 0; i + k <= n; i++)
{
p = pos;
reverse(p.begin() + i,p.begin() + i + k);
if (m.count(p) == 0)
{
m[p] = m[pos] + 1;
q.push_back(p);
}
}
}
return -1;
}
};