格子游戏
Problem Description
Alice和Bob玩了一个古老的游戏:首先画一个n*n的点阵,接着他们两个轮流在相邻的点之间画上虚边和粗边,直到围成一个封闭的圈(面积不必为1)为止,“封圈”的那个人就是赢家。因为棋盘实在是太大了(n<=200),他们的游戏实在是长了!他们甚至在游戏中都不知道谁赢得了游戏。于是请你写一个程序,帮助他们计算他们是否结束了游戏?
Input
每组输入数据第一行为两个整数n和m。m表示一共画了m条线。以后m行,每行首先有两个数字(x,y),代表了画线的起点坐标,接着用空格隔开一个字符,假如字符是“D”,则是向下连一条边,如果是“R”就是向右连一条边。输入数据不会有重复的边且保证正确。
Output
对于每组数据,输出一行:在第几步的时候结束。假如m步之后也没有结束,则输出一行“draw”。
Sample Input
3 5 1 1 D 1 1 R 1 2 D 2 1 R 2 2 D
Sample Output
4
思路
因为读入的边的两个端点a和b在同一个集合,那么就说明连起来一个圈了,
因为已知find(a)到a有边,find(b)到b有边,那么如果find(a)=find(b),就是一个封闭的圈了
二维变一维简单的维度转换然后就是relation的裸题了,
注意维度转换和初始化以及没有结束的情况记得输出,没啦。
1 program game; 2 const 3 inf='game.in'; 4 outf='game.out'; 5 var 6 father:array[0..40000] of longint; 7 i,n,m,a,b,t1,t2:longint; 8 cz:char; 9 10 function find(apple:longint):longint; 11 begin 12 if father[apple]<>apple then father[apple]:=find(father[apple]); 13 exit(father[apple]); 14 end; 15 16 procedure union(aa,bb:longint); 17 begin 18 father[bb]:=aa; 19 end; 20 21 procedure outgo(); 22 begin 23 writeln(i); 24 close(input); 25 close(output); 26 halt; 27 end; 28 29 begin 30 assign(input,inf); 31 assign(output,outf); 32 reset(input); rewrite(output); 33 34 readln(n,m); 35 for i:= 1 to n*n do 36 father[i]:=i; //init; 37 38 for i:= 1 to m do 39 begin 40 read(a,b); 41 a:=n*(a-1)+b; 42 read(cz); readln(cz); 43 if cz='R'then b:=a+1 44 else b:=a+n; 45 t1:=find(a); 46 t2:=find(b); 47 if t1<>t2 then union(t1,t2) 48 else outgo; 49 end; 50 51 writeln('draw'); 52 close(input); 53 close(output); 54 end.