В игру «черный ящик» играют с помощью квадратного черного ящика, который располагается на плоском столе. На каждой из сторон ящика есть n отверстий (всего 4n отверстий), в которые можно вбрасывать шар. Вброшенный шар через некоторое время вылетит наружу через одно из 4n отверстий, возможно, через то же отверстие, в которое он был вброшен.
Содержимое черного ящика можно рассматривать в виде сетки размером n x n. Отверстия в сторонах ящика – это начала и концы строк и столбцов сетки. Каждая клетка сетки либо пустая, либо занята отражателем. Отражатель – это устройство, которое изменяет направление движения шара на 90 градусов. Рассмотрим пример ящика размером 5x 5.
Вброшенный шар движется по прямой, пока не попадает в отражатель или не вылетит наружу. Когда шар попадает в отражатель, шар меняет направление своего движения, а отражатель меняет свое положение (под словом «меняет» подразумевается поворот на 90 градусов). На примере показаны действия отражателя.
a) Первый шар вброшен через отверстие. Он попал в отражатель и изменил направление движения.
b) После попадания первого шара отражатель изменил свое положение. Новый шар вбросили в то же отверстие, он попал в тот же отражатель, и отразился в направлении, противоположном направлению первого шара после отражения.
c) Отражатель изменил свое положение. После каждого попадания положение отражателя изменяется.
Когда шар попадает в отражатель, раздается звуковой сигнал. Количество отражений шара можно узнать, посчитав количество сигналов. Можно доказать, что шар всегда вылетает из ящика. У ящика есть одна кнопка, которая приводит его в исходное положение, и другая кнопка, которая меняет положение всех отражателей на противоположное.
ЗАДАНИЕ
Вам будет предоставлен интерфейс к 15 черным ящикам с помощью библиотеки функций Pascal или C/C++. Вы должны определить содержимое каждого из ящиков как можно точнее и отправить на проверку файлы, описывающие каждый ящик. Интерфейс также предоставляет возможность создания собственных ящиков для тестирования.
ОГРАНИЧЕНИЯ
1 ≤ n ≤ 30
ВЫВОД
Вы должны предоставить на проверку файлы, содержащие следующие данные для каждого из 15 черных ящиков:
blackboxK.out |
ОПИСАНИЕ |
#FILE blackbox K
.....
.../.
....
.../.
.?.?. |
СТРОКА 1: Заголовок файла, который должен иметь вид
#FILE blackbox K
где K (число в диапазоне 1..15) соответствует ящику, для которого найдено решение.
n СТРОК: Каждая строка описывает строку ящика, начиная с верхней и заканчивая нижней. Каждая строка должна содержать ровно n символов, соответствующих клеткам, находящимся на пересечении этой строки и столбцов (слева направо).
·Символ ‘.’ обозначает, что клетка пуста.
·Символ ‘/’ обозначает, что в клетке находится отражатель с исходным положением ‘/’
·Символ ‘’ обозначает, что в клетке находится отражатель с исходным положением ‘’
·Символ ‘?’ обозначает, что Вы не смогли определить исходное содержимое клетки |
БИБЛИОТЕКА
Вам будет предоставлена библиотека, которая содержит следующие функции:
ФУНКЦИЯ |
Описание |
PASCAL
function Initialize(box: integer): integer;
C/C++
int Initialize(int box); |
Инициализирует библиотеку. Эта функция должна вызываться один раз в начале программы. Она возвращает значение n – количество отверстий на каждой стороне ящика.
Параметр box должен содержать целое число в пределах от 1 до 15, указывающее номер ящика, который Вы хотите использовать, или 0, если Вы хотите использовать ящик, созданный Вами. |
PASCAL
function throwBall(holeIn, sideIn: integer;
var holeOut, sideOut: integer): longint;
C
int throwBall(int holeIn, int sideIn,
int *holeOut, int *sideOut);
C++
int throwBall(int holeIn, int sideIn,
int &holeOut, int &sideOut); |
Вбрасывает шар в ящик через отверстие с номером holeIn на стороне sideIn. Стороны пронумерованы следующим образом: 1 – Верхняя, 2 – Правая, 3 – Нижняя и 4 – Левая. Отверстия пронумерованы слева направо и сверху вниз, начиная с номера 1 на каждой стороне. В параметрах holeOut и sideOut функция возвращает номер отверстия и номер стороны – место, где шар вылетел наружу. В качестве своего значения функция throwBall возвращает количество звуковых сигналов, вызванных попаданиями шара в отражатели. |
PASCAL
procedure ResetBox;
C/C++
Void ResetBox(); |
Возвращает все отражатели в исходное положение. |
PASCAL
procedure ToggleDeflectors;
C/C++
Void ToggleDeflectors(); |
Меняет положения всех отражателей в ящике на противоположные. |
PASCAL
procedure Finalize;
C/C++
Void Finalize(); |
Корректно заканчивает взаимодействие с ящиком. Эта функция должна вызываться в конце Вашей программы. |
Чтобы использовать библиотеку в Вашей программе, необходимо выполнить следующее:
·FreePascal: В каталоге задачи есть файлы pbblib .o и pbblib. ppu. Чтобы их использовать, необходимо добавить следующую строку в Вашу программу
uses pbblib;
В файле pblackbox.pas представлен пример использования библиотеки.
·C: В каталоге задачи есть файлы cbblib.o и cbblib.h. Чтобы их использовать, необходимо добавить следующую директиву в Вашу программу
#include “cbblib.h”
В файле cblackbox.c представлен пример использования библиотеки. Чтобы скомпилировать код, используйте следующую команду
gcc –o yourprogram cbblib.o yourprogram.c
·C++: В каталоге задачи есть файлы cppbblib.o и cppbblib.h. Чтобы их использовать, необходимо добавить следующую директиву в Вашу программу
#include “cppbblib.h”
В файле cppblackbox .cpp представлен пример использования библиотеки. Чтобы скомпилировать код, используйте следующую команду
g++ –o yourprogram cppbblib.o yourprogram.cpp
ЗАМЕЧАНИЕ: В любой момент времени может быть запущено не более одной программы, работающей с библиотекой.
ПРИМЕР ВЗАИМОДЕЙСТВИЯ
Ниже представлен пример взаимодействия с ящиком, изображенным ранее на рисунке:
ВЫЗОВ ФУНКЦИИ |
ВОЗВРАЩЕННОЕ ЗНАЧЕНИЕ |
Initialize(0); |
Пусть программа взаимодействует с ящиком, изображенным на рисунке. Тогда функция возвращает значение 5, означая, что n = 5. |
PASCAL
throwBall(3,4,holeOut,sideOut );
C
throwBall(3,4,&holeOut,&sideOut);
C++
throwBall(3,4,holeOut,sideOut); |
Шар вбрасывается в отверстие с номером 3 (третье сверху) на левой стороне. Возвращается значение 1 – это означает, что шар отразился один раз. После возврата из функции, переменная holeOut содержит значение 2, а переменная sideOut содержит значение 3, то есть шар вылетел через отверстие с номером 2 (второе слева) нижней стороны ящика. |
ЭКСПЕРИМЕНТИРОВАНИЕ
Если Вы передадите значение 0 в функцию Initialize, библиотека прочитает содержимое ящика из файла blackbox.in. Так Вы сможете экспериментировать с библиотекой. Формат файла blackbox.in описан ниже.
blackbox.in |
ОПИСАНИЕ |
5
3
2 3
4 2 /
4 4 / |
СТРОКА 1: Содержит целое число n, которое задает количество отверстий на каждой стороне.
СТРОКА 2: Содержит целое число d , которое задает количество отражателей в ящике.
СЛЕДУЮЩИЕ d СТРОК: Каждый отражатель описывается одной строкой. Каждая строка содержит два целых числа, разделенных пробелом, которые задают номер столбца и строки, где расположен отражатель. После второго числа через один пробел записан символ, который может быть ‘/’ или ‘’ и определяет исходное положение отражателя. |
ЗАМЕЧАНИЕ: Файл blackbox. in из примера описывает ящик, изображенный вверху страницы 1.
СООБЩЕНИЯ ОБ ОШИБКАХ
В случае любых проблем библиотека выведет сообщение об ошибке в стандартный поток вывода ошибок. Возможные сообщения об ошибке и их значения приведены в нижеследующей таблице.
СООБЩЕНИЕ |
ЗНАЧЕНИЕ |
ERR 1 More than one app |
Только одна программа может одновременно работать с черными ящиками, перезапустите все программы и запускайте их строго по одной. |
ERR 2 Invalid box |
Переданный вами номер ящика не лежит в пределах от 0 до 15. |
ERR 3 Invalid deflector |
В файле blackbox.in находится отражатель в некорректной клетке. |
ERR 4 Invalid symbol |
В файле blackbox.in обнаружен недопустимый символ. |
ERR 5 Invalid size |
Размер ящика в файле blackbox. in задан неверно. |
ERR 6 Invalid input hole |
Либо сторона, либо отверстие вбрасывания шара заданы неверно. |
ERR 7 ALARM |
Пожалуйста, обратитесь к техническому персоналу. |