Прежде всего вспомним задачу “Взрывоопасность”. Идея, положенная в основу ее решения, заработает и здесь. Итак, разбиваем все полоски из плиток на 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;