Трехмерные ладьи
Игра в трехмерные шахматы ведется на кубическом поле N×N×N. Трехмерная ладья может ходить на любое число клеток по прямой в любом из шести направлений (в любую сторону в каждом из трех направлений).
На таком поле расставлены K ладей. Напишите программу, которая определит, бьют они все поле или нет.

Формат входных данных
В первой строке входного файла записано натуральное число N (1≤N≤1000), задающее размеры игрового куба, и количество ладей K (0≤K≤106). Далее записано K троек чисел, задающих координаты ладей (координата по каждому измерению — натуральное число от 1 до N).

Формат выходных данных
Выведите в выходной файл слово YES, если эти ладьи бьют весь куб, и слово NO в противном случае. В случае NO выведите во второй строке координаты какой-нибудь клетки, которая не бьется ни одной из ладей.

Построим три проекции расстановки ладей на грани куба. Тогда, фиксированная клетка (x,y,z) бьется хотя бы одной ладьей, если какая-то из ладей бьет хотя бы одну из клеток (x,y), (y,z), (x,z) на соответствующих проекциях. Таким образом, проверку одной клетки можно организовать за O(1).
for x:=1 to n do
for y:=1 to n do
for z:=1 to n do
if (xy[x,y]=0)and (zy[z,y]=0) and (xz[x,z]=0) then // …. нашли небьющуюся клетку.

Но такое решение работает за время N^3 и при заданных ограничениях на N не проходит по времени. Чтобы оптимизировать решение, можно использовать битовые операции, тогда за одну операцию мы проверим сразу несколько клеток (например, 32 или 64):
for y:=1 to n do
for z:=1 to n do
if yz[y,z]=0 then
for k:=1 to n div 64 do
if (yx[y,k] or zx[z,k])<>(2^64)-1 then // … группу клеток, в которых есть небьющиеся.

Тогда время работы будет (N^3)/64 или для максимального N порядка 10^7.
This site was made on Tilda — a website builder that helps to create a website without any code
Create a website