HDU 3622 Bomb Game(二分+2SAT)

题意:有一个游戏,有n个回合,每回合可以在指定的2个区域之一放炸弹,炸弹范围是一个圈,要求每回合的炸弹范围没有重合。得分是炸弹半径最小的值。求可以得到的最大分数。

思路:二分+2SAT。

二分炸弹范围,再根据有无重合建图,用2SAT判定。

#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;
const int maxn =105;
struct TwoSAT
{
    int n;
    vector<int> G[maxn*2];
    bool mark[maxn*2];
    int S[maxn*2],c;
    bool dfs(int x)
    {
        if(mark[x^1]) return false;
        if(mark[x]) return true;
        mark[x]=true;
        S[c++]=x;
        for(int i=0; i<G[x].size(); ++i)
            if(!dfs(G[x][i])) return false;
        return true;
    }
    void init(int n)
    {
        this->n=n;
        for(int i=0; i<n*2; ++i) G[i].clear();
        memset(mark,0,sizeof(mark));
    }
    void add_clause(int x,int xval,int y,int yval)
    {
        x=x*2+xval;
        y=y*2+yval;
        G[x^1].push_back(y);
        G[y^1].push_back(x);
    }
    bool solve()
    {
        for(int i=0; i<n*2; i+=2)
        {
            if(!mark[i]&&!mark[i+1])
            {
                c=0;
                if(!dfs(i))
                {
                    while(c>0) mark[S[--c]]=false;
                    if(!dfs(i+1)) return false;
                }
            }
        }
        return true;
    }
};
struct Point
{
    int x,y;
};
Point p[105][2];
int n;
TwoSAT solver;
double distan(Point a,Point b)
{
    return sqrt((a.x*1.0-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool judge(double d)
{
    solver.init(n);
    for(int i=0; i<n; ++i)for(int a=0; a<2; ++a)
            for(int j=i+1; j<n; ++j)for(int b=0; b<2; ++b)
                    if(distan(p[i][a],p[j][b])<=2*d)
                        solver.add_clause(i,a^1,j,b^1);
    return solver.solve();
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {

        for(int i=0; i<n; ++i)
        {
            for(int j=0; j<2; ++j)
                scanf("%d%d",&p[i][j].x,&p[i][j].y);
        }
        double maxi=0;
        solver.init(n);
        for(int i=0; i<n; ++i)for(int a=0; a<2; ++a)
                for(int j=i+1; j<n; ++j)for(int b=0; b<2; ++b)
                        maxi=max(maxi,distan(p[i][a],p[j][b]));
        double L=0,R=maxi;
        for(int i=0; i<30; ++i)
        {
            double mid=(L+R)/2;
            if(judge(mid)) L=mid;
            else R=mid;
        }
        printf("%.2lf\n",L);
    }
    return 0;
}

HDU 3622 Bomb Game(二分+2SAT)

时间: 2024-10-12 16:11:18

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

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(二分+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 unbounde

【HDU】3622 Bomb Game(2-SAT)

http://acm.hdu.edu.cn/showproblem.php?pid=3622 又是各种逗.. 2-SAT是一种二元约束,每个点可以置于两种状态,但只能处于一种状态,然后图是否有解就是2-SAT啦. 看白书吧. x1和x2分别表示x处于1和x

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

hdu 3622 二分+2-sat

/* 二分+2-sat 题意:在一个二维平面上给你n个炸弹,和2*n个位置,每一行的两个位置仅仅能有一个放炸弹 如今炸弹爆炸有一个半径.当炸弹爆炸时两个炸弹的半径化成的圆不能相交,求最大半径 二分半径. 每次假设一个炸弹可放的两个位置中的一个与其它位置有矛盾,就进行建边.最后推断是否存在这样一组解 就可以. */ #include<stdio.h> #include<string.h> #include<math.h> #define eps 1e-5 #define

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