HDU 3622 Bomb Game(二分+2-SAT)

Bomb Game

Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5396    Accepted Submission(s): 1925

Problem Description

Robbie is playing an interesting computer game. The game field is an unbounded 2-dimensional region. There are N rounds in the game. At each round, the computer will give Robbie two places, and Robbie should choose one of them to put a bomb. The explosion area of the bomb is a circle whose center is just the chosen place. Robbie can control the power of the bomb, that is, he can control the radius of each circle. A strange requirement is that there should be no common area for any two circles. The final score is the minimum radius of all the N circles.
Robbie has cracked the game, and he has known all the candidate places of each round before the game starts. Now he wants to know the maximum score he can get with the optimal strategy.

Input

The first line of each test case is an integer N (2 <= N <= 100), indicating the number of rounds. Then N lines follow. The i-th line contains four integers x1i, y1i, x2i, y2i, indicating that the coordinates of the two candidate places of the i-th round are (x1i, y1i) and (x2i, y2i). All the coordinates are in the range [-10000, 10000].

Output

Output one float number for each test case, indicating the best possible score. The result should be rounded to two decimal places.

Sample Input

2

1 1 1 -1

-1 -1 -1 1

2

1 1 -1 -1

1 -1 -1 1

Sample Output

1.41

1.00

题目链接:HDU 3622

很明显的二分题,二分爆炸半径r使得被选中的炸弹的爆炸出的圆面积均没有相交(边缘可以重叠)即可。

代码:

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const double eps = 1e-5;
const int N = 110;
const int M = N * N * 4;
struct edge
{
    int to, nxt;
    edge() {}
    edge(int _to, int _nxt): to(_to), nxt(_nxt) {}
};
pii P[N];
edge E[M];
int head[N << 1], tot;
int dfn[N << 1], low[N << 1], st[N << 1], belong[N << 1], ts, scc, top;
bitset < N << 1 > ins;
int n;

void init()
{
    CLR(head, -1);
    tot = 0;
    CLR(dfn, 0);
    CLR(low, 0);
    CLR(belong, 0);
    ts = scc = top = 0;
    ins.reset();
}
inline void add(int s, int t)
{
    E[tot] = edge(t, head[s]);
    head[s] = tot++;
}
void Tarjan(int u)
{
    dfn[u] = low[u] = ++ts;
    st[top++] = u;
    ins[u] = 1;
    int i, v;
    for (i = head[u]; ~i; i = E[i].nxt)
    {
        v = E[i].to;
        if (!dfn[v])
        {
            Tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if (ins[v])

            low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u])
    {
        ++scc;
        do
        {
            v = st[--top];
            ins[v] = 0;
            belong[v] = scc;
        }
        while (u != v);
    }
}
inline double cal(const pii &a, const pii &b)
{
    return sqrt((a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second));
}
bool check(double r, int sz)
{
    init();
    int i, j;
    for (i = 0; i < sz; i += 2)
    {
        for (j = i + 2; j < sz; ++j)
        {
            double dx = cal(P[i], P[j]);
            if (dx < 2 * r)
            {
                add(i, j ^ 1);
                add(j, i ^ 1);
            }
        }
    }
    for (i = 1; i < sz; i += 2)
    {
        for (j = i + 1; j < sz; ++j)
        {
            double dx = cal(P[i], P[j]);
            if (dx < 2 * r)
            {
                add(i, j ^ 1);
                add(j, i ^ 1);
            }
        }
    }
    for (i = 0; i < sz; ++i)
        if (!dfn[i])
            Tarjan(i);
    for (i = 0; i < sz; ++i)
        if (belong[i] == belong[i ^ 1])
            return false;
    return true;
}
int main(void)
{
    int i;
    while (~scanf("%d", &n))
    {
        for (i = 0; i < (n << 1); i += 2)
            scanf("%d%d%d%d", &P[i].first, &P[i].second, &P[i | 1].first, &P[i | 1].second);
        double L = 0, R = 10000 * 1.45;
        double ans = 0;
        while (R - L >= eps)
        {
            double mid = (L + R) / 2.0;
            if (check(mid, n << 1))
            {
                L = mid;
                ans = mid;
            }
            else
                R = mid;
        }
        printf("%.2f\n", ans);
    }
    return 0;
}
时间: 2024-08-05 10:46:19

HDU 3622 Bomb Game(二分+2-SAT)的相关文章

HDU 3622 Bomb Game(二分+2SAT)

题意:有一个游戏,有n个回合,每回合可以在指定的2个区域之一放炸弹,炸弹范围是一个圈,要求每回合的炸弹范围没有重合.得分是炸弹半径最小的值.求可以得到的最大分数. 思路:二分+2SAT. 二分炸弹范围,再根据有无重合建图,用2SAT判定. #include <cstdio> #include <cmath> #include <vector> #include <cstring> using namespace std; const int maxn =10

HDU 3622 Bomb Game (二分+2-SAT)

题目地址:HDU 3622 先二分半径,然后小于该半径的不能选,对这些不能选的点对进行加边.然后判断可行性即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue

HDU - 3622 Bomb Game(二分+2-SAT)

题目大意:玩一个放炸弹游戏,有N次放炸弹的机会,每次放炸弹时,你都有两个位置可以选择,问如何放炸弹,能使爆炸的炸弹的半径的最小值最大(炸弹爆炸半径可以控制,但是爆炸形成的圈不能有重叠部分) 解题思路:最小值最大,二分 二分半径,如果有不满足的点,就建立起限制边,接着判断能否完成染色即可 #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <

HDU 3622 Bomb Game(2-sat)

HDU 3622 Bomb Game 题目链接 题意:求一个最大半径,使得每个二元组的点任选一个,可以得到所有圆两两不相交 思路:显然的二分半径,然后2-sat去判定即可 代码: #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <cmath> #include <algorithm> using namespace s

HDU 3622 Bomb Game

Bomb Game Time Limit: 3000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 362264-bit integer IO format: %I64d      Java class name: Main Robbie is playing an interesting computer game. The game field is an unbounded 2-dimens

HDOJ 3622 Bomb Game 2-sat

http://acm.hdu.edu.cn/showproblem.php?pid=3622 题意:上个月写的,题目好像是说一对点要选一个引爆,引爆半径自己选,任意两圆不能相交,最后分数是所有圆的最小半径,求最大分数. 分析:二分半径,2-sat判定可行性. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 using namespace std;

HDOJ 3622 Bomb Game

二分距离2sat Bomb Game Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3382    Accepted Submission(s): 1161 Problem Description Robbie is playing an interesting computer game. The game field is an

hdu 4185 Oil Skimming(二分匹配)

Oil Skimming Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 883    Accepted Submission(s): 374 Problem Description Thanks to a certain "green" resources company, there is a new profitable

hdu 3555 Bomb(数位dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 题目大意:就是给你一个数n,判断从0到n有多少个数含有数字49...... 是不是觉得跟hdu2089很相似呀... 思路:跟hdu2089一样的,注意给出的数比较大,所以这儿用__int64  .... code: #include<cstdio> #include<iostream> #include<cstring> #include<algorithm&