【Nov 1P1,爆搜之美】油滴扩展

      集训的第一天,真的好累...别的也不想说什么了,直接说下昨天的题吧。

  
    
【问题描述】
在一个长方形框子里,最多有N(
0 ≤N≤ 6 )个相异的点。在其中任何一个点上放一个很小的油滴.那么
这个油滴会一直扩展,直到接触判其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油
滴。那么应该按照怎样的顺序在这N个点上放置油滴,才能使放置完毕后所有油滴占据的总体积最大呢?
(不同的油滴不会相互融合)
【输入格式】
第一行一个整数N。
第二行为长方形边框一个顶点及其对角顶点的坐标.x,y,x’,y’,接下去N行.每行两个整数xi,yi.
表示盒子内N个点的坐标。
以上所有的整数都在[
- 1000 , 1000 ]
【输出格式】
一行,一个整数,长方形盒子剩余的最小空间(结果四舍五人输出)。
【输入样例】
2
0 0 10 10
3 3
7 7
【输出样倒】
50

 

 

      首先我们一眼看到的就是数据范围,n∈[0,6]。根据这个极其敏感的数据范围判断,这道题用暴力搜索(或者是枚举)应该是没问题的(何谓敏感?参见本博“根据数据范围估算时间复杂度”一文)。所以这道题的思路很简单,只要搜索每一个油滴,记录现在所有圆的面积,枚举结束后记录最大值(如果记录的是剩余面积就是最小值)然后回溯即可。甚至有的童鞋竟然打了6重循环的枚举,简单易懂,但是也能过,而且代码极其漂亮~

      虽然思路简单,但是还要注意一些细节。首先,点的个数是0到6个,要注意0,而且不要像某些人把点看成[-1000,1000]~其次,一定要注意油滴所在位置已经被扩展过的情况。这时如果不加处理,就会出现负面积,使结果偏小。

 

参考代码:

 

  
    
1 program box;
2 var
3 n,x,y,i:longint;
4 xa,ya,xb,yb:longint;
5 xx,yy: array [ 1 .. 6 ] of longint;
6 r: array [ 1 .. 6 ] of double;
7 v: array [ 1 .. 6 ] of boolean;
8 max,s:double;
9 function min(x,y:longint):longint;
10 begin
11 if x < y then exit(x)
12 else exit(y);
13 end ;
14 procedure dfs(x:longint);
15 var
16 i,j:integer;
17 ro,rt:double;
18 begin
19 if x > n then
20 begin
21 if s > max then max: = s;
22 exit;
23 end ;
24 for i: = 1 to n do
25 if not v[i] then
26 begin
27 ro: = 0 ; // 下面是找到四条边的最小值
28 ro: = min(min(min(abs(xx[i] - xa),abs(xx[i] - xb)),abs(yy[i] - ya)),abs(yy[i] - yb));
29 for j: = 1 to n do
30 if v[j] then
31 begin
32 rt: = sqrt(sqr(xx[i] - xx[j]) + sqr(yy[i] - yy[j])) - r[j];
33 if (rt < ro) then ro: = rt; // 找最小圆心距
34 end ;
35 if ro < 0 then ro: = 0 ; // 很重要,判断是否有负距离
36 v[i]: = true;
37 r[i]: = ro;
38 s: = s + pi * ro * ro;
39 dfs(x + 1 );
40 v[i]: = false;
41 s: = s - pi * r[i] * r[i];
42 r[i]: = 0 ;
43 end ;
44 end ;
45 begin
46 assign(input, ' box.in ' );
47 reset(input);
48 assign(output, ' box.out ' );
49 rewrite(output);
50 readln(n);
51 readln(xa,ya,xb,yb);
52 for i: = 1 to n do
53 readln(xx[i],yy[i]);
54 max: = 0 ; s: = 0 ;
55 fillchar(v,sizeof(v),false);
56 dfs( 1 );
57 writeln(round(abs(xa - xb) * abs(ya - yb) - max));
58 close(input);
59 close(output);
60 end .

 

(saltless原创,转载请注明出处)

你可能感兴趣的:(扩展)