- •Олимпиадные задачи и решения
- •Векторы (100 баллов)
- •Погодные условия (100 баллов)
- •Шоколадные плитки (100 баллов)
- •Работники (100 баллов)
- •Робот (100 баллов)
- •Зал Круглых Столов (100 баллов)
- •Вто (100 баллов)
- •Вишня (100 баллов)
- •Алхимия (100 баллов)
- •Цепь (100 баллов)
- •Казино (100 баллов)
- •Система уравнений (100 баллов)
- •Забавный конфуз
- •Соревнование
- •Абракадабра
- •Циферблат
- •Многоугольники
- •Квадрат
- •Лабиринт
- •Задача “Шифр”
- •Задача “Школы”
- •Последовательность
- •Автобус
- •Головоломка
- •Электронная почта
- •Виртуляндия
- •Конвейер
- •Новости
Шоколадные плитки (100 баллов)
Наверное, всем известно, что шоколад полезен для мозга человека. Поэтому участники национальной олимпиады страны Олимпия принесли на тур много плиток шоколада, чтобы гениальные идеи приходили к ним быстрее. Однако принесенного шоколада оказалось слишком много, и после тура в кабинете осталось N прямоугольных плиток, которые состояли из долей размерами 1×1. Двое участников решили съесть часть оставшегося шоколада, но, учитывая что во время тура они уже съели достаточно много шоколада, было решено сделать это достаточно необычным игровым способом, по следующим правилам.
У
частники
выполняют определенные операции с
шоколадными плитками по очереди: сначала
первый, потом второй, снова первый и
т.д. В свою очередь участник выбирает
плитку шоколада, с которой он будет
выполнять одну из следующих операций:
Разломить плитку на две; линия разлома должна проходить параллельно сторонам плитки и между долями.
Отломить и съесть произвольную «строку» или «столбик» плитки, который не есть крайним.
Отломить и съесть все доли плитки, которые находятся с краю, но чтобы после этого от плитки осталась хотя бы одна доля (минимальный размер плитки, c которой может быть произведена такая операция – 3×3).
Никакая из этих операций не может быть произведена с плиткой 1×1, поэтому все такие плитки остаются до конца игры. Проигрывает тот участник, который в свою очередь не может произвести ни одной из приведенных операций.
Задание
Напишите программу CHOCO, которая по информации о плитках шоколада, оставшихся после тура, определяет количество вариантов первого хода первого участника, гарантирующих ему выигрыш, при следовании выигрышной стратегии в дальнейшем.
Входные данные
В первой строке входного файла CHOCO.DAT содержится целое число N (1≤N≤100) – количество шоколадных плиток. Во второй строке содержатся N пар целых чисел, каждая i-ая из которых задает длину и ширину i-ой плитки. Длина и ширина не меньше чем 1 и не превышают 100.
Выходные данные
В единственной строке выходного файла CHOCO.SOL должно находиться целое число – количество вариантов первого хода первого участника, которые гарантируют ему выигрыш, при следовании оптимальной стратегии в дальнейшем.
Пример входных и выходных данных
|
CHOCO.DAT |
CHOCO.SOL |
|
1 3 3 |
3 |
Выигрышные ходы первого участника следующие: операция (3), операция (2) со второй строкой, и операция (2) со вторым столбиком.
{ fp }
(* Problem: CHOCO*)
{$I+,Q-,R-,S-}
const MAXN = 101;
MAXX = 101;
type
PointType = record
X, Y : integer;
end;
var a:array[1..MAXN]of pointtype;
p:array[1..MAXX,1..MAXX]of byte;
t:array[0..16]of byte;
o:text;
N,i,j,k,z,max,s:integer;
_1,_2,_3,_4,_5:longint;
begin
assign(o,'CHOCO.DAT');reset(o);
read(o,N);max:=0;
for i:=1 to N do
begin
read(o,a[i].x,a[i].y);if a[i].x>max then max:=a[i].x;if a[i].y>max then max:=a[i].y;
end;
close(o);
p[1,1]:=0;{1x1 is 0}
for i:=1 to max do for j:=i to max do
begin
fillchar(t,sizeof(t),0);
for k:=1 to i-1 do
begin
t[p[k,j] xor p[i-k,j]]:=1;
end;
for k:=1 to j-1 do
begin
t[p[i,k] xor p[i,j-k]]:=1;
end;
for k:=1 to i-2 do
begin
t[p[k,j] xor p[i-k-1,j]]:=1;
end;
for k:=1 to j-2 do
begin
t[p[i,k] xor p[i,j-k-1]]:=1;
end;
if (i>=3)and(j>=3) then t[p[i-2,j-2]]:=1;
for k:=0 to 16 do if t[k] = 0 then
begin
p[i,j]:=k;
p[j,i]:=k;
break;
end;
end;
assign(o,'CHOCO.SOL');rewrite(o);
s:=0;
for z:=1 to N do s:=s xor p[a[z].x,a[z].y];
for z:=1 to N do
begin
i:=a[z].x;j:=a[z].y;
{}
for k:=1 to i-1 do
begin
if s xor p[i,j] xor p[k,j] xor p[i-k,j] = 0 then
begin
inc(_2);
end;
end;
for k:=1 to j-1 do
begin
if s xor p[i,j] xor p[i,k] xor p[i,j-k]=0 then
begin
inc(_1);
end;
end;
for k:=1 to i-2 do
begin
if s xor p[i,j] xor p[k,j] xor p[i-k-1,j]=0 then
begin
inc(_4);
end;
end;
for k:=1 to j-2 do
begin
if s xor p[i,j] xor p[i,k] xor p[i,j-k-1]=0 then
begin
inc(_3);
end;
end;
if (i>=3)and(j>=3) then
begin
if s xor p[i,j] xor p[i-2,j-2] = 0 then inc(_5);
end;
end;
writeln(o,_1+_2+_3+_4+_5);
close(o);
end.
