zoukankan      html  css  js  c++  java
  • Bomb Game(求每组俩个圆心选择求固定半径的最大覆盖面积)

    题:http://acm.hdu.edu.cn/showproblem.php?pid=3622

    题意:给定n组俩个圆心选择,求固定半径能覆盖的最大面积;

    分析:显然半径越大面积覆盖越大,所以二分半径;

       判断合法就是用2-SAT去连边,以当前为半径的圆会和其他哪些圆冲突就选其对立面连接起来;

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<math.h>
    using namespace std;
    #define pb push_back
    const int M=202;
    const double eps=1e-5;
    double x[M],y[M];
    vector<int>g[M],rg[M],cb;
    int cmp[M],vis[M];
    int n,m;
    double dis(int i,int j){
        return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
    }
    void init(){
        cb.clear();
        for(int i=0;i<=2*n;i++) g[i].clear(),rg[i].clear(),cmp[i]=0;
        memset(vis,0,sizeof(vis));
    }
    void addedge(int u,int v){
        g[u].pb(v);
        rg[v].pb(u);
    }
    void dfs(int u){
        vis[u]=1;
        for(int i=0;i<g[u].size();i++)
            if(!vis[g[u][i]])
                dfs(g[u][i]);
        cb.pb(u);
    }
    void rdfs(int u,int k){
        vis[u]=1;
        cmp[u]=k;
        for(int i=0;i<rg[u].size();i++)
            if(!vis[rg[u][i]])
                rdfs(rg[u][i],k);
    }
    void scc(){
        for(int i=0;i<2*n;i++)
            if(!vis[i])
                dfs(i);
        int k=0;
        memset(vis,0,sizeof(vis));
        for(int i=cb.size()-1;i>=0;i--){
            if(!vis[cb[i]])
                rdfs(cb[i],k++);
        }
    }
    bool check(double r){
        init();
        for(int i=0;i<2*n-2;i++){
            int t;
            if(i%2==0)t=i+2;
            else t=i+1;
            for(int j=t;j<2*n;j++)
               if(dis(i,j)<2*r){
                  ///cout<<i+1<<" "<<(j^1)+1<<'
    ';
                 ///  cout<<j+1<<" "<<(i^1)+1<<'
    ';
                   addedge(i,j^1);
                   addedge(j,i^1);
               }
        }
        scc();
        for(int i=0;i<=2*n-2;i+=2)
        if(cmp[i]==cmp[i+1])
            return false;
        return true;
    }
    int main(){
        while(scanf("%d",&n)!=EOF){
            for(int i=0;i<n;i++)
                scanf("%lf%lf%lf%lf",&x[2*i],&y[2*i],&x[2*i+1],&y[2*i+1]);
            double l=0,r=40000.0;
            while(r-l>=eps){
                double midd=(l+r)/2;
                if(check(midd)) l=midd;
                else r=midd;
            }
            printf("%.2f
    ",r);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Bandit Wargame Level18 Writeup(interactive shell and .bashrc )
    Bandit Wargame Level12 Writeup
    Natas Wargame Level25 Writeup(头部注入+POST/GET注入)
    Mybatis 加载 Mapper配置的四种方式
    设计模式(四)---- 代理模式
    execute() 和 sumbit() 的区别
    Executors提供的四种线程池
    线程的三种实现方法
    同一个线程多次调用start()会出现的问题
    线程的介绍
  • 原文地址:https://www.cnblogs.com/starve/p/13823402.html
Copyright © 2011-2022 走看看