码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷1378

时间:2017-10-15 19:49:15      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:顺序   ret   ring   全排列   main   span   pre   点距   半径   

一道面向过程的搜索题

如果采用模块化的思想这道题会很好写。

先用dfs求出全排列,

然后我们写一个place函数,处理所有的拓展油滴情况即可

这样能够避免头晕以及不必要的调试。

#include<stdio.h>
#include<cmath>
#include<algorithm>
using namespace std;
int control[6];bool book[6];//存储全排列
int n;double res;
double d[6][6];
struct circle
{
    int x;int y;double r;
}c[6];
int x3;int y3;int x2;int y2;
double place(int p)//拓展油滴函数
{
    double minp=0x3f3f3f3f;double
    t=abs(x3-c[p].x);minp=min(minp,t);//printf("minpis%.4f\n",minp);
    t=abs(x2-c[p].x);minp=min(minp,t);//printf("minpis%.4f\n",minp);
    t=abs(y3-c[p].y);minp=min(minp,t);//printf("minpis%.4f\n",minp);
    t=abs(y2-c[p].y);minp=min(minp,t);//printf("minpis%.4f\n",minp);//更新四边距离
    for(int i=0;i<n;i++)
    {
        if(i==p)continue;//不能计算到自己的距离
        if(c[i].r>-0.000001&&c[i].r<0.000001)//如果目标点半径为0即跳过
        continue;
        t=d[p][i]-c[i].r;
        if(t<0.00001)return 0;//如果在油滴内部无法拓展
        minp=min(minp,t);//printf("minpis%.4f\n",minp);    
    }
    c[p].r=minp;
    return minp*minp;//return的是r^2最后再乘π
}
void clear()//清空半径
{
    for(int i=0;i<n;i++)
    {
        c[i].r=0;
    }return;
}
void dfs(int x)//求全排列
{
    if(x==n)
    {
        double rep=0;
        for(int i=0;i<n;i++)//按排列顺序放置油滴
        {
            rep+=place(control[i]);
        }
        if(res<rep)res=rep;
        clear();//记得清空半径
        return;
    }
    else//全排列模板
    {
        for(int i=0;i<n;i++)
        {
            if(!book[i])
            {
                book[i]=true;
                control[x]=i;
                dfs(x+1);
                book[i]=false;
            }
        }
    }
    return ;
}
int main()
{
    scanf("%d",&n);
    scanf("%d%d%d%d",&x3,&y3,&x2,&y2);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&c[i].x,&c[i].y);
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<i;j++)
        {
            d[j][i]=d[i][j]=
            sqrt((c[i].x-c[j].x)*(c[i].x-c[j].x)+(c[i].y-c[j].y)*(c[i].y-c[j].y));
            //printf("d[%d][%d]is%f\n",i,j,d[i][j]);
                        //计算任意两点距离
        }
    }
    dfs(0);//dfs
    res*=3.1415926;//由于res是Σri^2所以要乘π
    res=abs(x3-x2)*abs(y3-y2)-res+0.5;//减总面积,四舍五入
    int ans=res;
    printf("%d",ans);
    return 0;
}

洛谷1378

标签:顺序   ret   ring   全排列   main   span   pre   点距   半径   

原文地址:http://www.cnblogs.com/SHADOWICENCXIX/p/7672725.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!