• PKU 1379 Run Away(模拟退火算法)


    题目大意:原题链接  

    给出指定的区域,以及平面内的点集,求出一个该区域内一个点的坐标到点集中所有点的最小距离最大.

    解题思路:一开始想到用随机化算法解决,但是不知道如何实现。最后看了题解才知道原来是要用模拟退火算法解决。

    不过个人感觉这个算法的实现过程中仍然采用了随机化算法。二者均属于概率算法。  参考链接

    Point Goto_Rand_Dir(double key,Point temp)函数中,Point temp必须得定义在参数中,不能定义在函数内部,

    否则temp没有初始值,无法进行后面的加法运算.

    #include<ctime>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    const int shift=60;
    const double inf=1e10;
    const double pi=acos(-1.0);  
    struct Point 
    {
        double x,y;
    }p[1010],randp[4];
    
    double Get_Dis(Point a,Point b)
    {
        return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    }
    Point Get_Rand_Point(int a,int b)
    {
        Point temp;
        temp.x=rand()%a+1;
        temp.y=rand()%b+1;
        return temp;
    }
    Point Goto_Rand_Dir(double key,Point temp)
    {   
        double delta=2*pi*(double)rand()/RAND_MAX;
        temp.x+=key*sin(delta);
        temp.y+=key*cos(delta);
        return temp;
    }
    
    int main()
    {
        double dis[5];
        int i,j,k,T,x,y,m;
        scanf("%d",&T);
        srand(time(NULL));
        while(T--){
            double now;
            Point temp;
            scanf("%d%d%d",&x,&y,&m);
            for(i=1;i<=m;i++)
                scanf("%lf%lf",&p[i].x,&p[i].y);
            for(i=1;i<=4;i++){//分别往四个方向找四个方向的最小值
                dis[i]=inf; 
                randp[i]=Get_Rand_Point(x,y);//给randp[]数组随机取横纵坐标值
                for(j=1;j<=m;j++){
                    now=Get_Dis(randp[i],p[j]);
                    if(now<dis[i]) dis[i]=now;//dis[i]存的是最小值 
                }
            } 
            double key=sqrt(1.0*(x*x+y*y))/2;//关键 
            while(key>=0.01){//精度要求 
                for(i=1;i<=4;i++){
                    for(j=1;j<=shift;j++){
                        temp=randp[i];//采用之前四个方向确定的随机横纵坐标值 
                        temp=Goto_Rand_Dir(key,temp);
                        if(temp.x<0||temp.y<0||temp.x>x||temp.y>y) 
                            continue;
                        now=inf;
                        for(k=1;k<=m;k++){
                            double dist=Get_Dis(temp,p[k]);
                            if(now>dist) now=dist;//now存的是最小值 
                        }
                        if(now>dis[i]){
                            dis[i]=now;//dis[i]中存的是最小值最大 
                            randp[i]=temp;
                        }
                    }
                }
                key=key*0.8;
            }
            for(i=1,k=1;i<=4;i++)//在四个方向中找最小值最大 
                if(dis[i]>dis[k]) k=i;
            printf("The safest point is (%.1lf, %.1lf).
    ",randp[k].x,randp[k].y);
        }
    }
  • 相关阅读:
    mybatis的缓存机制
    mybatis动态SQL
    mybatis关联集合List&分布查询传递多列值
    winrt获取文件MD5码
    在wpf中使用winrt的Toast弹框效果
    winrt控件
    WdatePicker组件不显示
    Thread.Sleep in WinRT
    google 语音api
    UTF8编码转换(C#)
  • 原文地址:https://www.cnblogs.com/freinds/p/6486663.html
Copyright © 2020-2023  润新知