POJ 3004 && HDU 1922 Subway planning

题目大意:

平面直角坐标系中有一些点代表着一些城市。国家要在(0,0)点设置中心车站并向建设地铁线路,但要求线路是直线。某个城市可以使用地铁线路的前提是它与线路的直线距离不超过d。问最少建设多少条线路才能让所有的城市都能使用地铁。

解题思路:

扫描线+最小区间覆盖。

如图所示:对于任何一个点,都有一个铁路允许的设立的角度区间,在d固定的情况下,点距离原点越远区间越小。

因为是一个圆圈,所以要枚举任一点为区间覆盖的起点。

下面是代码:

#include <set>
#include <map>
#include <queue>
#include <math.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>

#define eps 1e-8
#define pi acos(-1.0)
#define inf 107374182
#define inf64 1152921504606846976
#define lc l,m,tr<<1
#define rc m + 1,r,tr<<1|1
#define iabs(x)  ((x) > 0 ? (x) : -(x))
#define clear1(A, X, SIZE) memset(A, X, sizeof(A[0]) * (SIZE))
#define clearall(A, X) memset(A, X, sizeof(A))
#define memcopy1(A , X, SIZE) memcpy(A , X ,sizeof(X[0])*(SIZE))
#define memcopyall(A, X) memcpy(A , X ,sizeof(X))
#define max( x, y )  ( ((x) > (y)) ? (x) : (y) )
#define min( x, y )  ( ((x) < (y)) ? (x) : (y) )

using namespace std;
struct node1
{
    double x,y,l,r;
    bool operator <(const node1 a)const
    {
        return l<a.l;
    }
} Point[1005];
int main()
{
    int n,T,ans,cnt;
    double d,temp,now,drift,r;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%lf",&n,&d);
        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf",&Point[i].x,&Point[i].y);
            temp=sqrt(Point[i].x*Point[i].x+Point[i].y*Point[i].y);
            if(temp<=d)
            {
                n--;
                i--;
            }
            else
            {
                if(Point[i].x==0)
                {
                    if(Point[i].y>0)now=0.5*pi;
                    else now=1.5*pi;
                }
                else if(Point[i].y==0)
                {
                    if(Point[i].x>0)now=0;
                    else now=pi;
                }
                else
                {
                    now=asin(iabs(Point[i].y)/temp);
                    if(Point[i].x<0&&Point[i].y>=0)now=pi-now;
                    else if(Point[i].x<=0&&Point[i].y<0)now+=pi;
                    else if(Point[i].x>0&&Point[i].y<=0)now=2*pi-now;
                }
                drift=asin(d/temp);
                //printf("*%lf %lf\n",now,drift);
                Point[i].l=now-drift;
                Point[i].r=now+drift;
            }
        }
        if(n==0)
        {
            puts("0");
            continue;
        }
        sort(Point,Point+n);
        for(int i=n; i<2*n; i++)
        {
            Point[i]=Point[i-n];
            Point[i].l+=2*pi;
            Point[i].r+=2*pi;
        }
        ans=inf;
        for(int i=0; i<n; i++)
        {
            r=Point[i].r;
            cnt=1;
            for(int j=i+1; j<n+i; j++)
            {

                if(r>Point[j].r)r=Point[j].r;
                else if(r<Point[j].l)
                {
                    cnt++;
                    r=Point[j].r;
                }
            }
            ans=min(ans,cnt);
        }
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-23 04:58:46

POJ 3004 && HDU 1922 Subway planning的相关文章

POJ 2411 &amp;&amp; HDU 1400 Mondriaan&#39;s Dream (状压dp 经典题)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12341   Accepted: 7204 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series

poj 1226 hdu 1238 Substrings 求若干字符串正串及反串的最长公共子串 2002亚洲赛天津预选题

题目:http://poj.org/problem?id=1226 http://acm.hdu.edu.cn/showproblem.php?pid=1238 其实用hash+lcp可能也可以,甚至可能写起来更快,不过我没试,我最近在练习后缀数组,所以来练手 后缀数组的典型用法之一----------------后缀数组+lcp+二分 思路:1.首先将所有的字符串每读取一个,就将其反转,作为一组,假设其下标为i到j,那么cnt[i]到cnt[j]都标记为一个数字(这个数字意思是第几个读入的字符

POJ 3340 &amp; HDU 2410 Barbara Bennett&#39;s Wild Numbers(数学)

题目链接: PKU:http://poj.org/problem?id=3340 HDU:http://acm.hdu.edu.cn/showproblem.php?pid=2410 Description A wild number is a string containing digits and question marks (like 36?1?8). A number X matches a wild number W if they have the same length, and

POJ 2492 || HDU 1829:A Bug&#39;s Life(并查集)

传送门: POJ:点击打开链接 HDU:点击打开链接 A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 27624   Accepted: 8979 Description Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they fe

POJ 2243 || HDU 1372:Knight Moves(BFS)

Knight Moves Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11223 Accepted: 6331 Description A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visit

POJ 2104&amp;HDU 2665 Kth number(主席树入门+离散化)

K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 50247   Accepted: 17101 Case Time Limit: 2000MS Description You are working for Macrohard company in data structures department. After failing your previous task about key inse

HDU 1158 Employment Planning (DP)

Problem Description A project manager wants to determine the number of the workers needed in every month. He does know the minimal number of the workers needed in each month. When he hires or fires a worker, there will be some extra cost. Once a work

最小生成树,POJ和HDU几道题目的解题报告(基于自己写的模板)

首先POJ题目: 链接:1251 Jungle Roads 题目大意:纯求最小生成树,结果为最小权值边的和.采用邻接表 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <queue> 5 using namespace std; 6 7 #define maxn 30 //最大顶点个数 8 int n; //顶点数,边数 9 10 struct arcn

POJ 1201 &amp;&amp; HDU 1384 Intervals(差分约束系统)

题目地址:POJ 1201   HDU 1384 根据题目意思,可以列出不等式如下: Sj-Si>=c; Si-S(i-1)>=0; S(i-1)-Si>=-1; 然后用最短路spfa来解决这个不等式.用max来当源点,0为终点.最终的-d[0]就是答案. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <