luogu cogs 油滴扩展

1076. [NOIP2010冲刺六] 油滴扩展

★   输入文件:oilbox.in   输出文件:oilbox.out   简单对比
时间限制:1 s   内存限制:128 MB

【题目描述】


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


【输入格式】


第一行一个整数N。

第二行为长方形边框一个顶点及其对角顶点的坐标,x,y,x',y’。

接下去N行,每行两个整数Xi,yi,表示盒子内N个点的坐标。

以上所有的整数都在[-1000,1000]内。


【输出格式】


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


【样例输入】

2

0 0 10 10

3 3

7 7


【样例输出】

50

【提示】


注:圆的面积公式S=pi*r*r,其中r为圆的半径,pi=3.1415926。

 

 1 #include<cmath>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstdio>
 5 using namespace std;
 6 int n,xa,ya,xb,yb;
 7 const double infd=100000000.0;//这个是对于double的INF 
 8 const double PI=acos(-1);//为了精度 
 9 double ans;
10 int x[10],y[10];
11 double r[10];
12 int seq[10];
13 int fact[10]={0,1,2,6,24,120,720};//阶乘值,其实就是全排列数 
14 double dist(int a,int b){//求两圆a,b的圆心距 
15     return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
16 }
17 void solve(){
18     double cur;//current answer目前的答案 
19     cur=abs(xa-xb)*abs(ya-yb);//刚开始还没被油滴覆盖,所以是整个盒子面积 
20     for(int i=0;i<n;i++){//对填充序列中的每个圆计算其在此情况下的半径 
21         double mr=infd;//当前圆的半径的最大值max radian(mr) 
22         mr=min(min(abs(x[seq[i]]-xa),abs(x[seq[i]]-xb)),min(abs(y[seq[i]]-ya),abs(y[seq[i]]-yb)));
23         //以上该行只考虑了盒子边界,未考虑其他之前填好的圆 
24         for(int j=0;j<i;j++){//现在考察之前扩展完毕的油滴 
25             double t=dist(seq[i],seq[j])-r[seq[j]];
26             //圆心距减去该圆半径,有可能有负数,此时本圆被包含在之前的圆中,需要特判,否则WA,60分 
27             mr=mr<max(t,(double)0)?mr:max(t,(double)0);//特判。三思而后提交!consider twice before you submit!
28         }
29         r[seq[i]]=mr;//记录该圆半径 
30         cur-=PI*mr*mr;//计算目前未被覆盖的面积 
31     }
32     ans=min(ans,cur);//更新答案 
33     return;
34 }
35 int main(){
36     freopen("oilbox.in","r",stdin);
37     freopen("oilbox.out","w",stdout);
38     cin>>n>>xa>>ya>>xb>>yb;
39     ans=abs(xa-xb)*abs(ya-yb);//初始化 
40     for(int i=0;i<n;i++){
41         seq[i]=i;
42         cin>>x[i]>>y[i];
43     }
44     for(int i=0;i<fact[n];i++){
45         solve();
46         next_permutation(seq,seq+n);//求下一个排列 
47     }
48     printf("%.0lf",ans);
49     return 0;
50 }

 

posted @ 2017-06-15 18:03  ioioioioioio  阅读(144)  评论(0编辑  收藏  举报