Subway planning
Time Limit: 2000MS Memory Limit: 65536K
Description
The government in a foreign country is looking into the possibility of establishing a subway system in its capital. Because of practical reasons, they would like each subway line to start at the central station and then go in a straight line in some angle as far as necessary. You have been hired to investigate whether such an approach is feasible. Given the coordinates of important places in the city as well as the maximum distance these places can be from a subway station (possibly the central station, which is already built), your job is to calculate the minimum number of subway lines needed. You may assume that any number of subway stations can be built along a subway line.
Figure 1: The figure above corresponds to the first data set in the example input.
Input
The first line in the input file contains an integer N, the number of data sets to follow. Each set starts with two integers, n and d (1 ≤ n ≤ 500, 0 ≤ d < 150). n is the number of important places in the city that must have a subway station nearby, and d is the maximum distance allowed between an important place and a subway station. Then comes n lines, each line containing two integers x and y (-100 ≤ x, y ≤ 100), the coordinates of an important place in the capital. The central station will always have coordinates 0, 0. All pairs of coordinates within a data set will be distinct (and none will be 0, 0).
Output
For each data set, output a single integer on a line by itself: the minimum number of subway lines needed to make sure all important places in the city is at a distance of at most d from a subway station.
Sample Input
2
7 1
-1 -4
-3 1
-3 -1
2 3
2 4
2 -2
6 -2
4 0
0 4
-12 18
0 27
-34 51
Sample Output
4
2
题意:平面直角坐标系中有一些点代表着一些城市。国家要在(0,0)点设置中心车站并向建设地铁线路,但要求线路是直线。某个城市可以使用地铁线路的前提是它与线路的直线距离不超过d。问最少建设多少条线路才能让所有的城市都能使用地铁。
分析:首先对于距离原点(0,0)的距离小于d的城市,我们没有必要取考虑,对于剩下的城市,我们可以算出每一个城市想要被地铁穿过的角度的范围 [Li,Ri] ,所以问题就转化为区间覆盖的问题,但是我们不知道以哪一个城市为起点会得到最优的解,所以要枚举一下起点。
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
const double eps = 1e-6;
const double Pi = acos(-1.0);
const int Max = 1100;
typedef struct node
{
double x,y;
double l,r;
node(){}
node(double _x,double _y):x(_x),y(_y){}
node operator + (const node &a)const
{
return node(x+a.x,y+a.y);
}
node operator - (const node &a)const
{
return node(x-a.x,y-a.y);
}
double operator * (const node &a)const
{
return a.x*x+a.y*y;
}
double operator ^ (const node &a)const
{
return x*a.y-y*a.x;
}
}Circ;
int dbcmp(double a)//精度控制
{
return fabs(a)<eps?0:(a>0?1:-1);
}
int JudgeQuadrant(node a)// 判断象限
{
if(a.x >= 0 && a.y >= 0) return 1;
if(a.x < 0 && a.y >= 0) return 2;
if(a.x <= 0 && a.y < 0) return 3;
if(a.x > 0 && a.y < 0) return 4;
return 0;
}
double d;
double Judge(node a,int op)//计算区间
{
int ant = JudgeQuadrant(a);
double ans1 = fabs(asin(a.y/sqrt(a*a)));
if(ant==2) ans1 = Pi-ans1;
if(ant==3) ans1 = ans1+Pi;
if(ant==4) ans1 = 2*Pi -ans1;
if(op)
return ans1 - asin(d/sqrt(a*a));
else
return ans1 + asin(d/sqrt(a*a));
}
bool cmp(node a,node b)
{
return a.l<b.l;
}
Circ C[Max];
int n;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %lf",&n,&d);
for(int i = 0;i<n;i++)
{
scanf("%lf %lf",&C[i].x,&C[i].y);
if(dbcmp(d*d-C[i]*C[i])>=0)
{
i--,n--;
continue;
}
C[i].l = Judge(C[i],1);
C[i].r = Judge(C[i],0);
}
sort(C,C+n,cmp);
for(int i =n ;i<2*n;i++)
{
C[i] = C[i-n];
C[i].l +=2*Pi;
C[i].r +=2*Pi;
}
int ans = n;
for(int i = 0; i < n ; i++)
{
double r = C[i].r;
int ant = 1;
for(int j= i+1;j<i+n;j++)
{
if(dbcmp(r-C[j].r)>=0) r =C[j].r;
else if(dbcmp(r-C[j].l)<0)
{
ant++;
r = C[j].r;
}
}
ans = min(ans,ant);
}
printf("%d\n",ans);
}
return 0;
}