zoukankan      html  css  js  c++  java
  • HDU

    题目大意:玩一个放炸弹游戏,有N次放炸弹的机会,每次放炸弹时,你都有两个位置能够选择。问怎样放炸弹,能使爆炸的炸弹的半径的最小值最大(炸弹爆炸半径能够控制,可是爆炸形成的圈不能有重叠部分)

    解题思路:最小值最大,二分
    二分半径,假设有不满足的点,就建立起限制边。接着推断是否能完毕染色就可以

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    using namespace std;
    #define esp 1e-5
    #define N 210 
    
    struct Node {
        int x, y;
    }node[N][2];
    
    bool mark[N];
    vector<int> G[N];
    int top, n, m;
    int S[N];
    
    void init (){
        for (int i = 0; i < n ; i++) {
            scanf("%d%d%d%d", &node[i][0].x, &node[i][0].y, &node[i][1].x, &node[i][1].y);
        }
    }
    double distance(int i, int a, int j, int b) {
        return sqrt( 1.0 * (node[i][a].x - node[j][b].x) * (node[i][a].x - node[j][b].x) + 1.0 * (node[i][a].y - node[j][b].y) * (node[i][a].y - node[j][b].y));
    }
    
    void AddEdge(int i, int a, int j, int b) {
        int x = i * 2 + a;
        int y = j * 2 + b;
        G[x ^ 1].push_back(y);
        G[y ^ 1].push_back(x);
    }
    
    bool dfs(int u) {
        if (mark[u ^ 1])
            return false;
        if (mark[u])
            return true;
        mark[u] = true;
        S[++top] = u;
        for (int i = 0; i < G[u].size(); i++)
            if (!dfs(G[u][i]))
                return false;
        return true;
    }
    
    bool judge(double mid) {
        for (int i = 0; i < 2 * n; i++)
            G[i].clear();
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                for (int a = 0; a < 2; a++)
                    for (int b = 0; b < 2; b++) {
                        //printf("dis is %lf
    ", distance(i, a, j, b));
                        if (2 * mid - distance(i, a, j, b) > esp) {
                            AddEdge(i, a, j, b);
                        }
                    }
                }
        }
    
        memset(mark, 0, sizeof(mark));
        for (int i = 0; i < 2 * n; i += 2) {
            if (!mark[i] && !mark[i ^ 1]) {
                top = 0;
                if (!dfs(i)) {
                    while(top) mark[S[top--]] = false;
                    if (!dfs(i ^ 1))
                        return false;
                }
            }
        }
        return true;
    }
    
    void solve() {
        double l = 0, r = 1e5;
        for (int i = 0; i < 30; i++) {
            double mid = (l + r) / 2;
    //      printf("l is %lf r is %lf mid is %lf
    ", l, r, mid);
            if (judge(mid))
                l = mid;
            else
                r = mid;
        }
        printf("%.2lf
    ", l);
    }
    
    int main() {
        while (scanf("%d", &n) != EOF) {
            init();
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    【第五年-创业路】
    【工具与解决方案】从做项目中积累学习
    【原理篇】人工智能
    【原理】分布式系统
    攻克Spring
    工具篇集锦
    最好用的JQuery插件集合以及组合拳
    设计模式 之状态模式
    设计模式 之组合模式
    设计模式之 封装算法
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7144155.html
Copyright © 2011-2022 走看看