洛谷 P1378 油滴扩展 dfs搜索

青春壹個敷衍的年華 提交于 2020-02-02 04:58:23

洛谷 P1378 油滴扩展 dfs搜索

题解:

dfs尝试所有的油滴放置顺序,找到总面积最大的一种。

代码如下:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<queue>
#include<cstring>
#include<vector>
#include<map>
#define MAX 10
#define PI 3.1415926
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,visit[MAX];
double r[MAX],x[MAX],y[MAX],xa,xb,ya,yb,maxl=0.0;
//r为每个油滴的半径,xa,xb,ya,yb为边界,maxl最油滴的最大总面积

double cal_r(int i){//计算当前点油滴的半径
    double dis1=min(fabs(x[i]-xa),fabs(x[i]-xb));
    double dis2=min(fabs(y[i]-ya),fabs(y[i]-yb));
    double dis=min(dis1,dis2);
    for(int j=0;j<n;j++){
        if(j!=i&&visit[j]){
            double d=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));//两个油滴圆心的距离
            dis=min(dis,max(d-r[j],0.0));//若i在j的内部,d-r[j]<0,不能存在这种情况
        }
    }
    return dis;
}

void dfs(int depth,double sum){
    if(depth==n){
        maxl=max(maxl,sum);
        return;
    }
    for(int i=0;i<n;i++){
        if(!visit[i]){
            r[i]=cal_r(i);//求第i个点的半径
            visit[i]=1;
            dfs(depth+1,sum+r[i]*r[i]*PI);
            visit[i]=0;
        }
    }
}

int main(){
    scanf("%d",&n);
    scanf("%lf%lf%lf%lf",&xa,&ya,&xb,&yb);
    double s=fabs(xa-xb)*fabs(ya-yb);//计算长方形边框的面积
    for(int i=0;i<n;i++){
        scanf("%lf%lf",&x[i],&y[i]);
    }
    dfs(0,0.0);
    printf("%d",(int)(s-maxl+0.5));
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!