hdu 3511 Prison Break

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

题意:

给出n个相离或包含的圆,问最里层的圆是第几层

竖着的扫描线与圆在最左侧相切时

1、线在圆的上方或下方无交点,则该圆在第1层

2、线在圆的上下方都有交点,且上下方的交点属于同一个圆C,则该圆在圆C的里面一层

3、线在圆的上下方都有交点,上方交于圆E,下方交于圆F,EF其中一个在另一个里面,则该圆与在里面的那个圆处在同一层

4、线在圆的上下方都有交点,上方交于圆E,下方交于圆F,EF在同一层,则该圆与EF在同一层

扫描线从左往右扫,用set维护当前扫描线与圆的交点的纵坐标,set在线修改排序规则(这波操作绝了)

每次取出圆上下的交点,计算圆的层次

一个圆往set里加两次,一次用于计算靠上的交点 一次用于计算靠下的交点 ,

往set里加的时候,这个圆与扫描线相切,交点纵坐标是一样的,如果set按交点坐标从大到小排序,必须先加那个用于靠上的交点的,以维持set里交点相对位置的正确。

set在线修改排序规则应该不能保证所有数据在新规则下有序,不过插入点的前一个和后一个好像是正确的

#include<set>
#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

#define N 50001

int line;

struct Line
{
    int id,xi;
}e[N<<1];

int lev[N];

bool equal(double a,double b)
{
    return abs(a-b)<1e-7;
}

struct Circle
{
    int x,y,r;

    double gety(int f)
    {
        double dy=sqrt(1.0*r*r-1.0*(line-x)*(line-x));
        return y+dy*f;
    }

}cir[N];

struct Node
{
    int id,tag;

    Node(){}
    Node(int id_,int tag_) : id(id_),tag(tag_) {}

    bool operator < (const Node p) const
    {
        double ya=cir[id].gety(tag),yb=cir[p.id].gety(p.tag);
        if(!equal(ya,yb)) return ya>yb;
        return tag>p.tag;
    }

};

set<Node>s; 

bool cmp(Line p,Line q)
{
    return p.xi<q.xi;
}

int main()
{
    int n,m,k,ld,rd,ans;
    set<Node>:: iterator l,r;
    while(scanf("%d",&n)!=EOF)
    {
        m=0;
        for(int i=0;i<n;++i)
        {
             scanf("%d%d%d",&cir[i].x,&cir[i].y,&cir[i].r);
             e[++m].id=i;
             e[m].xi=cir[i].x-cir[i].r;
            e[++m].id=i+n;
            e[m].xi=cir[i].x+cir[i].r;
        }
        sort(e+1,e+m+1,cmp);
        for(int i=1;i<=m;++i)
        {
            k=e[i].id%n;
            line=e[i].xi;
            if(e[i].id<n)
            {
                s.insert(Node(k,1));
                l=s.lower_bound(Node(k,1));
                r=l;
                r++;
                if(l==s.begin() || r==s.end()) lev[e[i].id]=1;
                else
                {
                    l--;
                    ld=(*l).id;
                    rd=(*r).id;
                    if(ld==rd) lev[e[i].id]=lev[ld]+1;
                    else lev[e[i].id]=max(lev[ld],lev[rd]);
                }
                s.insert(Node(k,-1));
            }
            else
            {
                s.erase(Node(k,1));
                s.erase(Node(k,-1));
            }
        }
        ans=0;
        for(int i=0;i<n;++i) ans=max(ans,lev[i]);
        printf("%d\n",ans);
    }
    return 0;
}    

Prison Break

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2206    Accepted Submission(s): 714

Problem Description

To save Sara, Michael Scofield was captured by evil policemen and he was arrested in Prison again. As is known to all, nothing can stop Michael, so Prison Break continues.
The prison consists of many circular walls. These walls won‘t intersect or tangent to each other.

Now Michael is arrested in one of the deepest rooms, and he wants to know how many walls he has to break at least for running out. In figure 1, Michael has to break 3 walls at least and in figure 2, 2 walls are needed.

Input

There will be multiple test cases (no more than 10) in a test data.
For each test case, the first line contains one number: n (1<=n<=50,000) indicating the total number of circular walls.
Then n lines follow, each line contains three integers x, y, r. (x,y) indicates the center of circular wall and r indicates the radius of the wall.
-100,000<=x,y<=100,000
1 <= r <= 100,000
The input ends up with EOF.

Output

The least number of walls to break for running out.

Sample Input

3
0 0 1
0 0 2
0 0 3
3
0 0 10
5 0 1
-5 0 1

Sample Output

3
2

Source

2010 ACM-ICPC Multi-University Training Contest(8)——Host by ECNU

原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12209904.html

时间: 2024-08-04 05:54:02

hdu 3511 Prison Break的相关文章

HDU 3681 Prison Break(bfs+二分+状压DP)

Prison Break Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3778    Accepted Submission(s): 992 Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But on

hdu 3681 Prison Break(状态压缩+bfs)

Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one day, the king of Rompire was captured by human beings. His thinking circuit was changed by human and thus became a tyrant. All those who are against him

hdu 3681 Prison Break (状态压缩+bfs+最短路)

Prison Break Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3214    Accepted Submission(s): 829 Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But on

【状压+二分+BFS】HDU 3681 Prison Break

通道:http://acm.hdu.edu.cn/showproblem.php?pid=3681 题意:机器人从F出发,走到G可以充电,D不能走进,走到Y关掉开关,要求把所有开关关掉,且电量最少,并求出初始最小电量. 思路:二分初始的电量,预处理任意G,Y,F之间的最短距离,然后状压dp[s][u]:状态为s的u为起点遍历整个图的最小布数. 代码:https://github.com/Mithril0rd/Rojo/blob/master/hdu3681.cpp TAG:代码来自华仔

HDU 3681 Prison Break floyd+状压+二分

题目链接:点击打开链接 题意: 给定n*m的矩阵: F:起点(有且仅有一个) D:坏点(不能走到这个点) G:能量池(走到这个点可以选择使用这个点的能量池,把电池充满,也可以暂时不用,只能使用一次) Y:目标点 问: 遍历所有Y点需要最小的电池容量是多少. 开始电池满电,每走一步消耗一格电. Y+G的个数<=15. n,m<=15 思路:状压YG,前面几位表示Y,后面几位表示G. 先跑个floyd,然后二分电池容量,状压dp判可行 #include <cstdio> #includ

HDU 3681 Prison Break

/* 给一个n*m的图,F代表起点,G代表充电池,一个充电池只能用一次,但可以用多个充电池,只能把电池充到最大(原始的电量),可以走过不用,D不能走, 问的是把所有的Y走一遍的原始的电量是多少 dp+状态压缩+二分+bfs dp[i][j]表示的状态是在i状态到达j的最大的电量 */ #include<stdio.h> #include<string.h> #include<queue> #define Max(a,b) a>b?a:b #define Min(a

HDU3681 Prison Break(状压dp)

Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one day, the king of Rompire was captured by human beings. His thinking circuit was changed by human and thus became a tyrant. All those who are against him

HDU 3861 Prison Breake 状态压缩dp+BFS+二分答案

题意:机器人有一个初始能量x,每走到G点时可选择充满能量(初始能量是满的),每走一步消耗一点能量,问当x最小为多少时,可以把所有的Y都走一遍,输出最小的x! 注意:G点和Y点加一起最多15个 附ac代码 #include<stdio.h> #include<string.h> #include<iostream> #include<queue> using namespace std; char map[16][16]; int dp[1<<16

1254 - Prison Break

  PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Michael Scofield has just broken out of the prison. Now he wants to go to a certain city for his next unfinished job. As you are the only programmer on his gang, he asked yo