Матч 39, Линейный город (LinearCity)

 

В линейном городе все дома расположены на прямой, и люди знают только свое относительное местоположение относительно друг друга. Информация о домах задана в строке refSource и массивах source и destination: i - ый элемент refSource указывает на направление, в котором требуется идти чтобы попасть из дома source[i] в дом destination[i]. Города пронумерованы числами от 0 до n – 1 (здесь n равно числу домов в городе).

Приезжий хочет установить относительное расположение некоторых пар домов. У него имеются массивы чисел source и destination. Для каждого значения i (0 £ i £ k – 1, k – длина массива source) необходимо установить, справа или слева от source[i] находится destination[i]. Соответственно вернуть следует слово “LEFT” или “RIGHT”. Если их относительного положения установить невозможно, то вернуть “UNKNOWN”.

 

Класс: LinearCity

Метод: vector<string> getReference(vector<int> refSource,

                             vector<int> refDestination,

                             string refDirection, int n,

                             vector<int> source, vector<int> destination)

Ограничения: refSource содержит от 1 до 50 элементов, 0 £ refSource[i], refDestination[i], source[i],  destination[i]  £ n – 1, refSource[i] ¹ refDestination[i]  для каждого 0 £ i £ m – 1 (m – длина массива refSource), каждый символ refDirection равен ‘L’ или ‘R’, 2 £ n £ 50, source[i] ¹ destination[i]  для каждого 0 £ i £ k - 1 (k – длина массива source).

 

Вход. Строка refSource и массивы source и destination, задающие информацию об относительном расположении некоторых пар городов, число городов n, массивы source и destination, содержащие запросы к городу.

 

Выход. Массив строк, i - ый элемент которого равен “LEFT”, “RIGHT” или “UNKNOWN” в зависимости от взаимного расположения городов source[i] и destination[i].

 

Пример входа

refSource

refDestination

refDirection

n

source

destination

{1, 2}

{2, 0}

“RR”

3

{1, 0}

{0, 1}

{1, 0}

{2, 2}

“RL”

3

{1, 0}

{0, 1}

{2, 3, 1, 0, 2, 0, 5, 5}

{1, 4, 4, 4, 4, 3, 2, 3}

"RLRLRLLL"

6

{0, 1, 0}

{2, 3, 5}

 

Пример выхода

{"RIGHT", "LEFT"}

{"RIGHT", "LEFT"}

{"LEFT", "RIGHT", "UNKNOWN"}

 

 

РЕШЕНИЕ

транзитивное замыкание

 

Заведем двумерный массив m, в котором установим m[i][j] = 1, если по условию задачи i - ый город расположен левее j - ого. Иначе положим m[i][j] = 0. Если refDirection[i] = 'R', то устанавливаем m[refSource[i]][refDestination[i]] = 1, иначе город refDestination[i] находится левее refSource[i], поэтому устанавливаем m[refDestination[i]][refSource[i]] = 1.

Запустим алгоритм транзитивного замыкания на графе, матрица смежности которого находится в матрице m. Теперь m[i][j] = 1, если мы точно можем установить, что i - ый город расположен левее j - ого. То есть если m[source[i]][destination[i]] = 1, то выводим “RIGHT”. Если m[destination[i]][source[i]] = 1, то выводим “LEFT”. Если m[source[i]][destination[i]] = 0, то ничего установить про относительное расположение городов с номерами destination[i] и source[i] нельзя, поэтому возвращаем "UNKNOWN".

 

ПРОГРАММА

 

#include <cstdio>

#include <vector>

#include <string>

using namespace std;

 

int m[50][50];

 

class LinearCity

{

public:

 vector<string> getReference(vector<int> refSource,

                             vector<int> refDestination,

                             string refDirection, int n,

                             vector<int> source, vector<int> destination)

 {

   int i, j, k;

   vector<string> res;

   memset(m,0,sizeof(m));

   for(i = 0; i < refSource.size(); i++)

     if (refDirection[i] == 'R')

       m[refSource[i]][refDestination[i]] = 1;

     else m[refDestination[i]][refSource[i]] = 1;

   for(k = 0; k < n; k++)

     for(i = 0; i < n; i++)

       for(j = 0; j < n; j++)

         if (m[i][k] && m[k][j]) m[i][j] = 1;

   for(i = 0; i < source.size(); i++)

   {

     if (m[source[i]][destination[i]] == 1) res.push_back("RIGHT"); else

     if (m[destination[i]][source[i]] == 1) res.push_back("LEFT"); else

     res.push_back("UNKNOWN");

   }

   return res;

 }

};