UVA 10691 - Subway(贪心+区间选点)
2014-02-18 17:51
381 查看
Problem D
Subway
Input: standard input
Output: standard output
Time Limit: 4 seconds
The government in a foreign land 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. You have been given the coordinates of important places in the city which must lie close to a subway station (possibly the central station). Exactly how close they must
lie is determined by another parameter, also given. Your job is to calculate the minimum number of subway lines needed to satisfy the demands of the government. You may assume that any number of subway stations can be built along a subway line.
The first line in the input file contains an integer N, the number of data sets to follow (at most 20). Each set starts with two integers, n and d (1<=n<=200, 0<=d<150). n is the number of important places in the city that must have a subway station nearby,
/*The figure above corresponds to the first sample input*/
题意:要建铁路,以(0,0)为点,给n个站点,要求站点距离不能铁路超过d。问最少建几条铁路。
思路:每个站点可以构造出最左和最右满足的铁路,就形成一个区间,那么就变成区间选点问题,不过由于是一个圆周,要从每个位置作为起点进行一次区间选点。还要注意精度误差。还要注意一开始角度的处理。。
代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N = 205;
const double pi = acos(-1.0);
int t, n, qn;
double d, x, y;
struct Q {
double l, r;
}q[N * 2];
double cal(double x, double y) {
return sqrt(x * x + y * y);
}
bool cmp(Q a, Q b) {
return a.r < b.r;
}
int solve() {
int ans = qn, i;
sort(q, q + qn, cmp);
for (i = 0; i < qn; i++) {
q[i + qn].l = q[i].l + 2 * pi;
q[i + qn].r = q[i].r + 2 * pi;
}
for (i = 0; i < qn; i++) {
int num = 1; double v = q[i].r;
for (int j = i + 1; j < i + qn; j++) {
if (v - q[j].l < -1e-9) {
num++;
v = q[j].r;
}
}
ans = min(ans, num);
}
return ans;
}
int main() {
scanf("%d", &t);
while (t--) {
qn = 0;
scanf("%d%lf", &n, &d);
for (int i = 0; i < n; i++) {
scanf("%lf%lf", &x, &y);
if (cal(x, y) > d) {
double p = atan2(y, x);
double du = asin(d / cal(x, y));
q[qn].l = p - du; q[qn++].r = p + du;
if (q[qn - 1].r > pi) {
q[qn - 1].l -= 2 * pi;
q[qn - 1].r -= 2 * pi;
}
}
}
printf("%d\n", solve());
}
return 0;
}
Subway
Input: standard input
Output: standard output
Time Limit: 4 seconds
The government in a foreign land 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. You have been given the coordinates of important places in the city which must lie close to a subway station (possibly the central station). Exactly how close they must
lie is determined by another parameter, also given. Your job is to calculate the minimum number of subway lines needed to satisfy the demands of the government. You may assume that any number of subway stations can be built along a subway line.
Input
The first line in the input file contains an integer N, the number of data sets to follow (at most 20). Each set starts with two integers, n and d (1<=n<=200, 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 pair of coordinates within a data set will be distinct (and none will be 0,0).
/*The figure above corresponds to the first sample input*/
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 Output for 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 | 4 2 |
思路:每个站点可以构造出最左和最右满足的铁路,就形成一个区间,那么就变成区间选点问题,不过由于是一个圆周,要从每个位置作为起点进行一次区间选点。还要注意精度误差。还要注意一开始角度的处理。。
代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N = 205;
const double pi = acos(-1.0);
int t, n, qn;
double d, x, y;
struct Q {
double l, r;
}q[N * 2];
double cal(double x, double y) {
return sqrt(x * x + y * y);
}
bool cmp(Q a, Q b) {
return a.r < b.r;
}
int solve() {
int ans = qn, i;
sort(q, q + qn, cmp);
for (i = 0; i < qn; i++) {
q[i + qn].l = q[i].l + 2 * pi;
q[i + qn].r = q[i].r + 2 * pi;
}
for (i = 0; i < qn; i++) {
int num = 1; double v = q[i].r;
for (int j = i + 1; j < i + qn; j++) {
if (v - q[j].l < -1e-9) {
num++;
v = q[j].r;
}
}
ans = min(ans, num);
}
return ans;
}
int main() {
scanf("%d", &t);
while (t--) {
qn = 0;
scanf("%d%lf", &n, &d);
for (int i = 0; i < n; i++) {
scanf("%lf%lf", &x, &y);
if (cal(x, y) > d) {
double p = atan2(y, x);
double du = asin(d / cal(x, y));
q[qn].l = p - du; q[qn++].r = p + du;
if (q[qn - 1].r > pi) {
q[qn - 1].l -= 2 * pi;
q[qn - 1].r -= 2 * pi;
}
}
}
printf("%d\n", solve());
}
return 0;
}
相关文章推荐
- uva 10691 - Subway(区间选点)
- uva 10148 Advertisement (贪心-区间选点)
- UVA-1615 Highway (贪心,区间选点)
- UVA - 10148 Advertisement(贪心 区间选点)
- UVA 10148 Advertisement (贪心 + 区间选点问题)
- Uva 11134 问题分解,贪心策略区间选点问题
- 初入算法篇(贪心)区间选点+uvalive2519
- UVA 10148 Advertisement (贪心 + 区间选点问题)
- UVa - 1615 Highway 高速公路 贪心+区间选点 重庆一中高2018级竞赛班第五次测试 2016.7.26 Problem 1
- UVa 1615 Highway (贪心,区间选点问题)
- UVA 1615 Highway (贪心, 区间选点)
- UVA 10148 Advertisement 贴广告的艺术 贪心 区间选点
- UVa 1193 / POJ 1328 / Beijing 2002 Radar Installation (贪心&区间选点)
- UVA 1615 Highway 区间选点 经典贪心 (SEERC 2005)
- 贪心——区间选点——xyoj 1782火柴字、xyoj 2080 Color the fence
- 贪心--区间选点问题
- uva 10382 Watering Grass(贪心-区间覆盖变形)
- 《黑书》uva10020最少区间覆盖(贪心)
- 步步为营(四)贪心(3)区间选点问题
- UVa 10382 - Watering Grass (贪心—区间覆盖)