JSOI2008 海战训练
JSOI2008 海战训练
【题目描述】
为了准备高层峰会,元首命令武装部队必须处于高度戒备。警察将监视每一条大街,军队将保卫建筑物,领空将布满了JS-2008飞机。此外,巡洋船只和舰队将被派去保护海岸线。但不幸的是因为种种原因,海军部仅有很少的几位军官能指挥大型海战。因此,他们考虑培养一些新的海军指挥官,为此选择了“海战”这一游戏来帮助训练。在这个著名的游戏中,一个方形的盘上放置了固定数量和形状的船只,每只船却不能碰到其它的船。在这个题中,我们仅考虑船是方形的,所有的船只都是由图形组成的方形。编写程序求出该棋盘上放置的船只的总数。
【输入文件】
输入文件头一行由用空格隔开的两个整数R和C组成,1<=R,C<=1000,这两个数分别表示游戏棋盘的行数和列数。接下来的R行每行包含C个字符,每个字符可以为“#”,也可为“.”,“#”表示船只的一部分,“.”表示水。
【输出文件】
为每一个段落输出一行解。如果船的位置放得正确(即棋盘上只存在相互之间不能接触的方形,如果两个“#”号上下相邻或左右相邻却分属两艘不同的船只,则称这两艘船相互接触了)。就输出一段话“There are S ships.”,S表示船只的数量。否则输出“Bad placement.”。
【输入样例】
6 8
.....#.#
##.....#
##.....#
.......#
#......#
#..#...#
【输出样例】
There are 5 ships.
【题目分析】
最近总在做水题……这个也算比较水了吧
用floodfill当然可以,不过出于个人习惯还是写了个并查集来记录联通块,然后记录每个联通块最小和最大的横纵坐标minx,maxx,miny,maxy,对每个联通块扫一遍看里面有木有“.”,有就无解,没有就输出联通块的个数。
【代码实现】
1 program tyvj1813;
2 var a:array[0..1001,0..1001]of char;
3 f:array[0..1000000]of longint;
4 b:array[0..1001,0..1001]of longint;
5 v:array[0..1000000]of boolean;
6 m,n,i,j,k:longint;
7 minx,miny,maxx,maxy:array[0..1000000]of longint;
8 function pd(x1,y1,x2,y2:longint):boolean;
9 var i,j:longint;
10 begin
11 for i:=x1 to x2 do
12 for j:=y1 to y2 do
13 if a[i,j]<>'#' then exit(false);
14 exit(true);
15 end;
16 function find(x:longint):longint;
17 begin
18 if f[x]<>x then f[x]:=find(f[x]);
19 exit(f[x]);
20 end;
21 procedure merge(x,y:longint);
22 begin
23 x:=find(x);y:=find(y);
24 if x<>y then
25 begin
26 f[x]:=y;
27 v[x]:=false;
28 end;
29 end;
30 function min(a,b:longint):longint;
31 begin
32 if a<b then exit(a)
33 else exit(b);
34 end;
35 function max(a,b:longint):longint;
36 begin
37 if a>b then exit(a)
38 else exit(b);
39 end;
40 begin
41 readln(m,n);
42 for i:=1 to m do
43 for j:=1 to n do
44 begin
45 inc(k);
46 b[i,j]:=k;
47 end;
48 for i:=1 to 1000000 do f[i]:=i;
49 for i:=1 to m do
50 begin
51 for j:=1 to n do
52 begin
53 read(a[i,j]);
54 if a[i,j]='.' then continue;
55 v[b[i,j]]:=true;
56 if a[i-1,j]='#' then merge(b[i,j],b[i-1,j]);
57 if a[i,j-1]='#' then merge(b[i,j],b[i,j-1]);
58 end;
59 readln;
60 end;
61 fillchar(minx,sizeof(minx),63);
62 fillchar(miny,sizeof(miny),63);
63 fillchar(maxx,sizeof(maxx),255);
64 fillchar(maxy,sizeof(maxy),255);
65 for i:=1 to m do
66 for j:=1 to n do
67 begin
68 if a[i,j]<>'#' then continue;
69 k:=find(b[i,j]);
70 minx[k]:=min(minx[k],i);
71 miny[k]:=min(miny[k],j);
72 maxx[k]:=max(maxx[k],i);
73 maxy[k]:=max(maxy[k],j);
74 end;
75 k:=0;
76 for i:=1 to 1000000 do
77 begin
78 if not v[i] then continue;
79 if not pd(minx[i],miny[i],maxx[i],maxy[i]) then
80 begin
81 writeln('Bad placement.');
82 halt;
83 end;
84 inc(k);
85 end;
86 writeln('There are ',k,' ships.');
87 end.