• [bzoj4852][Jsoi2016]炸弹攻击【随机化】


    【题目链接】
      https://www.lydsy.com/JudgeOnline/problem.php?id=4852
    【题解】
      在平面中随机选取一些点作为初始点,然后模拟退火。
      tip:在模拟退火时,由于答案比较小,但是温度比较高,所以在算exp时最好把相差的点数乘以一个常数让选取更差的的概率降低。
      

    /* --------------
        user Vanisher
        problem bzoj-4852 
    ----------------*/
    # include <bits/stdc++.h>
    # define    ll      long long
    # define    inf     0x3f3f3f3f
    # define    N       11
    # define    M       1010
    using namespace std;
    int read(){
        int tmp=0, fh=1; char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
        while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
        return tmp*fh;
    }
    struct Point{
        double x,y;
    }p[M];
    Point operator +(Point x, Point y){return (Point){x.x+y.x,x.y+y.y};}
    struct Circle{
        Point p;
        double r;
    }b[N];
    int n,m,ans;
    double mr;
    double sqr(double x){return x*x;}
    double dis(Point x, Point y){
        return sqrt(sqr(x.x-y.x)+sqr(x.y-y.y));
    }
    double rand_0_1(){return (rand() % 32767) / 32767.0;}
    double solve(Point x){
        double r=mr; double cnt=0;
        for (int i=1; i<=n; i++)
            r=min(r,dis(b[i].p,x)-b[i].r);
        if (r<0) return 0;
        for (int i=1; i<=m; i++)
            if (dis(x,p[i])<=r) cnt++;
        return cnt;
    }
    int Simulate_Anneal(Point ths, double S, double P, double Lim){
        double mx=solve(ths), now=mx, tmp;
        Point nex;
        for (double t=S; t>=Lim; t=t*P){
            double step = t * mr / S + 0.1;
            nex.x=ths.x+(2*step)*rand_0_1()-step;
            nex.y=ths.y+(2*step)*rand_0_1()-step;
            tmp=solve(nex);
            if (tmp>now) ths=nex, now=tmp;
                else if (exp(1e4*(tmp-now)/t)>rand_0_1())
                    ths=nex, now=tmp;
            mx=max(now,mx);
        }
        return mx;
    }
    int main(){
        n=read(), m=read(), mr=read();
        for (int i=1; i<=n; i++)
            b[i].p.x=read(), b[i].p.y=read(), b[i].r=read();
        for (int i=1; i<=m; i++)
            p[i].x=read(), p[i].y=read();
        for (int i=1; i<=20; i++)
            ans=max(ans,Simulate_Anneal((Point){2*mr*rand_0_1()-mr,2*mr*rand_0_1()-mr},mr,0.998,0.01));
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    GreenDao 数据库:使用Raw文件夹下的数据库文件以及数据库升级
    德鲁克的经典五问
    【转】太用力的人跑不远
    Android ViewPager打造3D画廊
    转载:张一鸣:10年面试2000人,我发现混的好的人,全都有同一个特质
    Comparable与Comparator
    Iterator、Iteratable与ListIterator
    shell 数学运算总结
    ADB命令行工具使用
    Android 搭建ssh服务
  • 原文地址:https://www.cnblogs.com/Vanisher/p/9135960.html
Copyright © 2020-2023  润新知