HDU 3622 Bomb Game

Bomb Game

Time Limit: 3000ms

Memory Limit: 32768KB

This problem will be judged on HDU. Original ID: 3622
64-bit integer IO format: %I64d      Java class name: Main

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

Source

2010 Asia Regional Tianjin Site —— Online Contest

解题:每行两颗弹,择其一而炸之,但是相邻两弹的爆炸范围不能相交,可以相切,所有弹爆炸范围相同,求最大的爆炸范围。

典型的2-SAT。求最大,就二分好了。

注意精度,至少1e-5,否则会WA.

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <climits>
  7 #include <vector>
  8 #include <queue>
  9 #include <cstdlib>
 10 #include <string>
 11 #include <set>
 12 #include <stack>
 13 #define LL long long
 14 #define pii pair<int,int>
 15 #define INF 0x3f3f3f3f
 16 using namespace std;
 17 const int maxn = 250;
 18 const double exps = 1e-5;
 19 struct arc{
 20     int to,next;
 21     arc(int x = 0,int y = -1){
 22         to = x;
 23         next = y;
 24     }
 25 };
 26 struct node{
 27     int x,y;
 28 };
 29 node p[maxn];
 30 arc e[maxn*maxn*10];
 31 int head[maxn],tot,dfn[maxn],low[maxn],belong[maxn],scc,cnt,n;
 32 bool instack[maxn];
 33 stack<int>stk;
 34 void add(int u,int v){
 35     e[tot] = arc(v,head[u]);
 36     head[u] = tot++;
 37 }
 38 double dis(const node &a,const node &b){
 39     double tmp = (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
 40     return sqrt(tmp);
 41 }
 42 void tarjan(int u){
 43     dfn[u] = low[u] = ++cnt;
 44     stk.push(u);
 45     instack[u] = true;
 46     for(int i = head[u]; ~i; i = e[i].next){
 47         if(!dfn[e[i].to]){
 48             tarjan(e[i].to);
 49             low[u] = min(low[u],low[e[i].to]);
 50         }else if(instack[e[i].to]) low[u] = min(low[u],dfn[e[i].to]);
 51     }
 52     if(low[u] == dfn[u]){
 53         scc++;
 54         int v;
 55         do{
 56             v = stk.top();
 57             stk.pop();
 58             instack[v] = false;
 59             belong[v] = scc;
 60         }while(v != u);
 61     }
 62 }
 63 bool solve(){
 64     while(!stk.empty()) stk.pop();
 65     for(int i = 0; i < maxn; i++){
 66         belong[i] = dfn[i] = low[i] = 0;
 67         instack[i] = false;
 68     }
 69     scc = cnt = 0;
 70     for(int i = 0; i < n<<1; i++)
 71         if(!dfn[i]) tarjan(i);
 72     for(int i = 0; i < n; i++)
 73         if(belong[i<<1] == belong[i<<1|1]) return false;
 74     return true;
 75 }
 76 int main() {
 77     int x,y;
 78     double low,high,mid;
 79     while(~scanf("%d",&n)){
 80         for(int i = 0; i < n; i++)
 81             scanf("%d %d %d %d",&p[i<<1].x,&p[i<<1].y,&p[i<<1|1].x,&p[i<<1|1].y);
 82         low = 0;
 83         high = 2000.0;
 84         while(fabs(high - low) > exps){
 85             mid = (high + low)/2.0;
 86             memset(head,-1,sizeof(head));
 87             for(int i = tot = 0; i < (n-1)<<1; i++){
 88                 for(int j = i&1?i+1:i+2; j < n<<1; j++){
 89                     if(dis(p[i],p[j]) < 2.0*mid){//i与j不能共存
 90                         add(i,j^1);
 91                         add(j,i^1);
 92                     }
 93                 }
 94             }
 95             if(solve()) low = mid;
 96             else high = mid;
 97         }
 98         printf("%.2f\n",high);
 99     }
100     return 0;
101 }

时间: 2024-10-24 11:54:37

HDU 3622 Bomb Game的相关文章

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

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)

题目地址: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 <

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;

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&

[ACM] hdu 3555 Bomb (数位DP,统计1-N中含有“49”的总数)

Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 7187 Accepted Submission(s): 2512 Problem Description The counter-terrorists found a time bomb in the dust. But this time the terrorists impro

HDU - 3555 Bomb (数位DP)

题意:求1-n里有多少人包含"49"的数字 思路:数位DP,分三种情况:到第i位没有49的情况,到第i位没有49且最高位是9的情况,到第i位有49的情况,将三种情况都考虑进去就是了 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; long long dp[30][3], n; int arr