超级马(sup)
Description
在一个无限的棋盘上有一个超级马,它可以完成各种动作。每一
种动作都是通过两个整数来确定——第一个数说明列的数(正数向右,
负数向左),第二个数说明行的数(正数向上,负数向下),移动马
来完成这个动作。
编写一个程序,从文本文件SUP.IN输入说明各种超级马的数据库。
对每一个超级马进行确认,是否通过自己的行动可以到达盘面上
的每一个区。
将结果存储到文本文件SUP.OUT。
Format
Input Format
在文本文件SUP.IN 的第一行中存在一个整数k,它代表数据库的
数1≤k≤100。在这个数字后出现K 数据库。它们的每一个第一行中会
出现整数N,它是马能够完成的各种动作的数,1≤n≤100。接下来数据
库的每一个行中包含两个整数P 和Q,它们由单个空格分开,说明动
作,-100≤p,q≤100。
Output Format
文本文件SUP.OUT 应由K 行组成,当第i 个数据库的超级马可
以到达棋盘面的每一个区,第i 行应包含一个词TAK,而另一个词NIE
则恰恰相反。
Sample
Sample Input
2
3
1 0
0 1
-2 -1
5
3 4
-3 -6
2 -2
5 6
-1 4
Sample Output
TAK
NIE
分析
因为题目中说明|p|,|q|在100以内,所以直接搜-100到100的棋盘,只要源点及上下左右四个点能够到达,那么整个图就全部能够到达。
代码如下
program sup;
type rec=record
x,y:longint;
end;
var k,p,q,i,j,n:longint;
flag:boolean;
dx:array[1..10000] of longint;
dy:array[1..10000] of longint;
queue:array[1..4000000] of rec;
visited:array[-101..101,-101..101] of boolean;
head,rear:longint;
procedure bfs;
var i,j,k,x,y:longint;
begin
head:=1;
rear:=1;
queue[head].x:=0;
queue[head].y:=0;
visited[0,0]:=true;
while head<=rear do
begin
for k:=1 to n do
begin
x:=queue[head].x+dx[k];
y:=queue[head].y+dy[k];
if (x>=-101) and (x<=101) and (y>=-101) and (y<=101) and (not visited[x,y])
then
begin
inc(rear);
queue[rear].x:=x;
queue[rear].y:=y;
visited[x,y]:=true;
if visited[0,1] and visited[0,-1] and (visited[1,0]) and visited[-1,0]
then
begin
writeln('TAK');
flag:=true;
exit;
end;
end;
end;
inc(head);
end;
end;
begin
readln(k);
while k<>0 do
begin
dec(k);
readln(n);
for i:=1 to n do
begin
readln(dy[i],dx[i]);
end;
fillchar(visited,sizeof(visited),false);
flag:=false;
bfs;
if not flag then writeln('NIE');
end;
end.