USACO the castle

题目翻译来自http://www.nocow.cn/index.php/Translate:USACO/castle

描述

我们憨厚的USACO主人公农夫约翰(Farmer John)以无法想象的运气,在他生日那天收到了一份特别的礼物:一张“幸运爱尔兰”(一种彩票)。结果这张彩票让他获得了这次比赛唯一的奖品——坐落于爱尔兰郊外的一座梦幻般的城堡!

喜欢吹嘘的农夫约翰立刻回到有着吹嘘传统的威斯康辛老家开始吹嘘了, 农夫约翰想要告诉他的奶牛们关于他城堡的一切。他需要做一些吹嘘前的准备工作:比如说知道城堡有多少个房间,每个房间有多大。另外,农夫约翰想要把一面单独的墙(指两个单位间的墙)拆掉以形成一个更大的房间。 你的工作就是帮农夫约翰做以上的准备,算出房间数与房间的大小。

城堡的平面图被划分成M*N(1 <=M,N<=50)个正方形的单位,一个这样的单位可以有0到4面墙环绕。城堡周围一定有外墙环绕以遮风挡雨。(就是说平面图的四周一定是墙。)


请仔细研究下面这个有注解的城堡平面图:

    1   2   3   4   5   6   7
  #############################
1 #   |   #   |   #   |   |   #
  #####---#####---#---#####---#   
2 #   #   |   #   #   #   #   #
  #---#####---#####---#####---#
3 #   |   |   #   #   #   #   #   
  #---#########---#####---#---#
4 # ->#   |   |   |   |   #   #   
  #############################

 

# =墙壁    -,| = 没有墙壁
-> =指向一面墙,这面墙推掉的话我们就有一间最大的新房间

友情提示,这个城堡的平面图是7×4个单位的。一个“房间”的是平面图中一个由“#”、“-”、“|”围成的格子(就是图里面的那一个个的格子)。比如说这个样例就有5个房间。(大小分别为9、7、3、1、8个单位(排名不分先后))

移去箭头所指的那面墙,可以使2个房间合为一个新房间,且比移去其他墙所形成的房间都大。(原文为:Removing the wall marked by the arrow merges a pair of rooms to make the largest possible room that can be made by removing a single wall. )

城堡保证至少有2个房间,而且一定有一面墙可以被移走。

格式

PROGRAM NAME: castle

INPUT FORMAT: 第一行有两个整数:M和N 城堡的平面图用一个由数字组成的矩阵表示,一个数字表示一个单位,矩阵有N行M列。输入与样例的图一致。

每一个单位的数字告诉我们这个单位的东西南北是否有墙存在。每个数字是由以下四个整数的某个或某几个或一个都没有加起来的。

1: 在西面有墙
2: 在北面有墙
4: 在东面有墙
8: 在南面有墙

城堡内部的墙会被规定两次。比如说(1,1)南面的墙,亦会被标记为(2,1)北面的墙。


OUTPUT FORMAT:

(file castle.out)

输出包含如下4行:

第 1 行: 城堡的房间数目。

第 2 行: 最大的房间的大小

第 3 行: 移除一面墙能得到的最大的房间的大小

第 4 行: 移除哪面墙可以得到面积最大的新房间。

选择最佳的墙来推倒。有多解时选最靠西的,仍然有多解时选最靠南的。同一格子北边的墙比东边的墙更优先。

用该墙的南邻单位的北墙或西邻单位的东墙来表示这面墙,方法是输出邻近单位的行数、列数和墙的方位("N"(北)或者"E"(东))。

SAMPLE INPUT

7 4
11 6 11 6 3 10 6
7 9 6 13 5 15 5
1 10 12 7 13 7 5
13 11 10 8 10 12 13

SAMPLE OUTPUT

5
9
16
4 1 E

题解

usaco中排在Flood Fill Algorithms 后面  肯定用Flood Fill Algorithms了(实际前两个);后两个搜索就好了。

 1 {
 2 ID:fuzhong2
 3 PROG:castle
 4 LANG:PASCAL
 5 }
 6 var
 7   num,c,d:array[1..50,1..50]of longint;
 8   f:array[0..51,0..51,1..4]of boolean;
 9   m,n,i,j:longint;
10 procedure pw;
11   var
12     te:array[1..4] of longint = (1,2,4,8);
13     i,j,k:longint;
14   begin
15     for i:=1 to n do
16       for j:= 1 to m do
17         for k:= 4 downto 1 do
18           if num[i,j]>=te[k] then begin f[i,j,k]:=false; dec(num[i,j],te[k]); end;
19   end;
20 procedure work1;
21   var
22     maxc,co,i,j,x,k,l:longint;
23   procedure dfs(i,j,co:longint;var x:longint);
24     var
25       y:longint;
26     begin
27       if (f[i,j,1]) and (c[i,j-1]=0) then begin c[i,j-1]:=co;  inc(x); dfs(i,j-1,co,x); end;
28       if (f[i,j,2]) and (c[i-1,j]=0) then begin c[i-1,j]:=co;  inc(x); dfs(i-1,j,co,x); end;
29       if (f[i,j,3]) and (c[i,j+1]=0) then begin c[i,j+1]:=co;  inc(x); dfs(i,j+1,co,x); end;
30       if (f[i,j,4]) and (c[i+1,j]=0) then begin c[i+1,j]:=co;  inc(x); dfs(i+1,j,co,x); end;
31     end;
32   begin
33     co:=0;
34     fillchar(c,sizeof(c),0);
35     maxc:=-1;
36     for i:=1 to n do
37       for j:= 1 to m do
38         if c[i,j]=0 then
39         begin
40           x:=1;
41           inc(co);
42           c[i,j]:=co;
43           dfs(i,j,co,x);
44             for k:=1 to n do
45               for l:= 1 to m do
46                 if c[k,l]=co then d[k,l]:=x;
47           if x>maxc then maxc:=x;
48         end;
49     writeln(co);
50     writeln(maxc);
51   end;
52   procedure work2;
53     var
54       temp:array[1..2,1..2]  of longint= ((-1,0),(0,1));
55       mi,mj,maxs,nk,i,j,k:longint;
56     begin
57       maxs:=-1;
58       for j:=m downto 1 do
59       for i:= 1 to n do
60       for k:=2 downto 1  do
61               if (i+temp[k,1]>=1) and(j+temp[k,2]<=m) then
62           begin
63               if (not (c[i,j]=c[i+temp[k,1],j+temp[k,2]]))and(maxs<=d[i,j]+d[i+temp[k,1],j+temp[k,2]]) then
64               begin
65                 mi:=i;
66                 mj:=j;
67                 maxs:=d[i,j]+d[i+temp[k,1],j+temp[k,2]];
68                 nk:=k;
69               end;
70               end;
71      writeln(maxs);
72      write(mi,' ',mj,' ');
73      if nk=1 then writeln('N') else writeln('E');
74     end;
75 begin
76   assign(input,'castle.in');reset(input);
77   assign(output,'castle.out');rewrite(output);
78   fillchar(f,sizeof(f),true);
79   read(m,n);
80   for i:= 1 to n do
81     for j:=1 to m do
82       read(num[i,j]);
83   pw;
84   work1;
85 {  for i:= 1 to n do  // 调试时用的可以无视
86      begin
87     for j:=1 to m do
88      write(d[i,j],' ');
89      writeln;
90      end;  }
91      work2;
92   close(input);
93   close(output);
94 end.
USER: fu zhongqing [fuzhong2]
TASK: castle
LANG: PASCAL

Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [0.000 secs, 316 KB]
   Test 2: TEST OK [0.000 secs, 316 KB]
   Test 3: TEST OK [0.000 secs, 316 KB]
   Test 4: TEST OK [0.000 secs, 316 KB]
   Test 5: TEST OK [0.000 secs, 316 KB]
   Test 6: TEST OK [0.000 secs, 316 KB]
   Test 7: TEST OK [0.032 secs, 316 KB]
   Test 8: TEST OK [0.000 secs, 316 KB]

All tests OK.

Your program ('castle') produced all correct answers! This is your submission #17 for this problem. Congratulations!  

(吐槽:用了17次、、、、、在后两个东西南北哪里纠结了一个小时);

posted @ 2012-10-28 09:55  付忠庆  阅读(235)  评论(0编辑  收藏  举报