Прежде всего вспомним задачу “Взрывоопасность”. Идея, положенная в основу ее решения, заработает и здесь. Итак, разбиваем все полоски из плиток на 64 группы (соответственно количеству матриц смежности), нумеруя их следующим образом. Берем все возможные матрицы смежности (всего их 64) и выписываем 6 букв из матриц подряд (то, что ниже главной диагонали, нас не интересует, так как никакой информации не несет). Меняем “Y” на “1”, а “N” на “0” и получаем двоичный код нашей группы. Каждую из групп дополнительно разобьем на три подгруппы, в зависимости от плитки, лежащей справа. Теперь наращиваем полоску вновь справа. Прописать вручную все 576 (64 группы, 3 подгруппы, 3 наращиваемых цвета) возможных комбинаций невозможно. К счастью, рассматривать группы нет необходимости, если воспользоваться битовой арифметикой. Достаточно рассмотреть всевозможные пары крайних плиток и определить смежность, которую они образуют. Она способна в каждой группе либо превратить “N” в “Y” (если ранее не встречалась), либо ничего не изменить. Определив позицию возможного изменения, создаем маску, в которой все биты равны нулю, кроме изменяемого. Остается только применить полученную маску к каждой группе (путем логического “или”). Не стоит забывать, что все эти операции производятся над длинными числами.
Function Check(i, j : shortint; s : integer) : integer;
var r, k : integer;
begin
if i > j then begin k := j; j := i; i := k end;
if i = 2 then j := j + 2;
if i = 3 then j := j + 3;
r := 1;
for k := 1 to j - 1 do r := r * 2;
Check := s or r; {применяем маску r к группе s}
end;
...
for i := 0 to 63 do
begin
for l := 1 to 3 do
for k := 1 to 3 do
begin
NewS := Check(l, k, i);{определяем новый номер группы}
Add(Na[News][k], A[i][l], Na[NewS][k]);{и добавляем в нее все, что было в старой}
{Na[News][k] := Na[News][k] + A[i][l] — аналог в обычной арифметике}
end
end;