Скачиваний:
35
Добавлен:
01.05.2014
Размер:
1.1 Mб
Скачать

80

Олимпиадные задачи и решения

Векторы 1

Погодные условия 3

Шоколадные плитки 5

Работники 7

Робот 8

Зал Круглых Столов 10

ВТО 13

Вишня 14

Алхимия 19

Цепь 21

Казино 23

Система уравнений 27

Забавный конфуз 30

Соревнование 31

Абракадабра 33

Циферблат 34

Кубики 37

Многоугольники 38

Пути 40

Квадрат 44

Лабиринт 46

Задача “Шифр” 48

Задача “Школы” 50

Последовательность 54

Автобус 55

Головоломка 56

Электронная почта 61

Виртуляндия 63

Конвейер 68

Новости 71

Лото 73

Парк 74

Пещера 76

Векторы (100 баллов)

На плоскости задано множество точек (x, y), где x, y – целые числа, 1≤xM, 1≤yN. Из каждой точки выходит ровно один из следующих векторов: (-1,-1), (-1,0), (-1,1), (0,1), (1,1), (1,0), (1,-1), (0,-1). Каждый вектор соединяет одну целочисленную точку плоскости с другой. Например, если из точке (2, 5) выходит вектор (1, 1), то он соединяет эту точку с (3, 6), но не наоборот.

Последовательность из двух и более точек плоскости a1, a2,…, ak назовем циклом, если каждая точка ai соединена вектором с ai+1 (1≤ik-1), и ak соединена вектором с a1. Циклы считаются разными если они отличаются хотя бы одной вершиной.

Задание

Напишите программу VECTORS, которая по информации о векторах, выходящих из точек плоскости, находит количество различных циклов.

Входные данные

Первая строка входного файла VECTORS.DAT содержит два целых числа N (1≤N≤100) и M (1≤M≤100). Каждая из последующих N строк, содержит M пар чисел (т.е. 2M чисел). Пара x, которая находится в строке y, задает вектор в точке (x, y).

Выходные данные

Единственная строка выходного файла VECTORS.SOL должна содержать целое число – количество циклов, образованных векторами.

Пример входных и выходных данных

VECTORS.DAT

VECTORS.SOL

2 4

-1 1 -1 1 -1 0 0 1

1 0 1 0 0 -1 0 -1

2

{ fp }

(* Problem: VECTORS*)

{$I+,Q+,R+,S-}

Var x,y: array[0..101,0..101] of integer;

a: array[0..101,0..101] of boolean;

i,j,ii,jj,co,xx,yy,n,m,nom,count: integer;

fi,fo: Text;

Begin

Assign(fi,'vectors.dat'); reset(fi);

Readln(fi,N,M);

For i:=1 to N do Begin

For j:=1 to M do Begin Read(fi,jj,ii); x[i,j]:=jj; y[i,j]:=ii;

a[i,j]:=true; yy:=i+ii; xx:=j+jj; a[yy,xx]:=true;

co:=0;

While (x[yy,xx]<>0) or (y[yy,xx]<>0) do Begin inc(co);

ii:=y[yy,xx]; jj:=x[yy,xx]; inc(xx,jj); inc(yy,ii);

if (yy=i) and (xx=j) Then Begin inc(count); Break End;

if co>m*n Then Break;

End;

End; Readln(fi);

End;

Assign(fo,'vectors.sol'); rewrite(fo); Writeln(fo,count); Close(fo);

End.

{ fp }

program Vectors;

const

MAX_SIZE = 100;

FILE_IN = 'VECTORS.DAT';

FILE_OUT = 'VECTORS.SOL';

type

TVector = record

X : Integer;

Y : Integer;

end;

TColor = (WHITE, GREY, BLACK);

var

RowNum : Integer; {Number of rows}

ColNum : Integer; {Number of columns}

Field : array[1..MAX_SIZE, 1..MAX_SIZE] of TVector;

Colors : array[1..MAX_SIZE, 1..MAX_SIZE] of TColor;

Cycles : Integer;

procedure ReadVector(var Fin : Text; var Vec : TVector);

begin

Read(Fin, Vec.X, Vec.Y);

end;

procedure Init;

var

Row : Integer;

Col : Integer;

Fin : Text;

begin

{ Read the data from input file }

Assign(Fin, FILE_IN);

Reset(Fin);

ReadLn(Fin, RowNum, ColNum);

for Row:=1 to RowNum do

begin

for Col:=1 to ColNum do

begin

ReadVector(Fin, Field[Row, Col]);

end;

ReadLn(Fin);

end;

Close(fin);

{ Initialize the colors }

for Row:=1 to RowNum do

for Col:=1 to ColNum do

begin

Colors[Row, Col] := WHITE;

end;

{ Initialize the global counte r}

Cycles := 0;

end;

function FollowWhitePath(StartRow : Integer; StartCol : Integer) : Boolean;

var

Row : Integer;

Col : Integer;

Vec : TVector;

begin

FollowWhitePath := false;

Row := StartRow;

Col := StartCol;

while (Colors[Row, Col] = WHITE) do

begin

Colors[Row, Col] := GREY;

Vec := Field[Row, Col];

Row := Row + Vec.Y;

Col := Col + Vec.X;

if (Row < 1) or (Row > RowNum) or (Col < 1) or (Col > ColNum) then exit;

end;

if (Colors[Row, Col] = GREY) then FollowWhitePath := true;

end;

procedure RepaintGreyPath(StartRow : Integer; StartCol : Integer);

var

Row : Integer;

Col : Integer;

Vec : TVector;

begin

Row := StartRow;

Col := StartCol;

while (Colors[Row, Col] = GREY) do

begin

Colors[Row, Col] := BLACK;

Vec := Field[Row, Col];

Row := Row + Vec.Y;

Col := Col + Vec.X;

if (Row < 1) or (Row > RowNum) or (Col < 1) or (Col > ColNum) then exit;

end;

end;

procedure Run;

var

Row : Integer;

Col : Integer;

CyclePath : Boolean;

begin

for Row:=1 to RowNum do

for Col:=1 to ColNum do

begin

if Colors[Row, Col] = WHITE then

begin

CyclePath := FollowWhitePath(Row, Col);

if CyclePath then Inc(Cycles);

RepaintGreyPath(Row, Col);

end;

end;

end;

procedure Done;

var

Fout : Text;

begin

Assign(Fout, FILE_OUT);

Rewrite(Fout);

WriteLn(Fout, Cycles);

Close(Fout);

end;

begin

Init;

Run;

Done;

end.