JZOJsenior1215.油滴扩展

油滴扩散问题求解
本文探讨了在一个长方形框中,如何通过合理的顺序放置油滴以最大化它们占据的空间。利用DFS深度优先搜索算法,结合具体示例进行了解题过程的详细说明。

Description

在一个长方型框子里,最多有N(0≤N≤6)个相异的点。在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其它油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这N个点上放置油滴,才能使放置完毕后所有油滴占据的总体积最大呢?(不同的油滴不会相互融合)
注:圆的面积公式V=pi*r*r,其中r为圆的半径。

Input

第一行一个整数N。
第二行为长方形边框一个顶点及其对角顶点的坐标,x,y,x’,y’。
接下去N行,每行两个整数xi,yi,表示盒子内N个点的坐标。
以上所有的整数都在[-1000, 1000]内。

Output

一行,一个整数,长方体盒子剩余的最小空间(结果四舍五入输出)。

Sample Input

2
0 0 10 10
3 3
7 7

Sample Output

50

Data Constraint

思路:
n不超过6,dfs就可以过了
注意细节,当一个点被以前的圆给包住了,那么半径为0,否则半径会为负,会WA
还有输入的点有可能前面的坐标比后面的大,记得加abs

代码:

var
        a,x,y,wx,wy:array[0..6]of longint;
        z,wz:array[0..6]of extended;
        bz:array[0..6]of boolean;
        n,i,j,xx,yy,xx1,yy1,tot:longint;
        ans:extended;
function max(x,y:extended):extended;
begin
        if x>y then exit(x);
        exit(y);
end;
function min(x,y:extended):extended;
begin
        if x<y then exit(x);
        exit(y);
end;
function dis(x,y,xx,yy:extended):extended;
begin
        exit(sqrt(sqr(x-xx)+sqr(y-yy)));
end;
procedure dfs(m:longint;v:extended);
var
        i,j:longint;
        k:extended;
begin
        if m>n then
        begin
                if v>ans then
                        ans:=v;
                exit;
        end;
        for i:=1 to n do
        if bz[i]then
        begin
                bz[i]:=false;
                k:=min(abs(x[i]-xx),abs(y[i]-yy));
                k:=min(k,min(abs(x[i]-xx1),abs(y[i]-yy1)));
                inc(tot);
                wx[tot]:=x[i];
                wy[tot]:=y[i];
                for j:=1 to tot-1 do
                        k:=min(k,max(dis(x[i],y[i],wx[j],wy[j])-wz[j],0));
                wz[tot]:=k;
                dfs(m+1,v+pi*k*k);
                dec(tot);
                bz[i]:=true;
        end;
end;
begin
        readln(n);
        readln(xx,yy,xx1,yy1);
        if n=0 then
        begin
                writeln(abs(xx1-xx)*abs(yy1-yy));
                halt;
        end;
        for i:=1 to n do readln(x[i],y[i]);
        fillchar(bz,sizeof(bz),true);
        dfs(1,0);
        writeln(round(abs(xx1-xx)*abs(yy1-yy)-ans));
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值