您的位置:首页 > 其它

POJ1066

2016-04-19 23:13 225 查看
Problem: Treasure Hunt

Description: 一个正方形区域,里面有很多墙,这些墙的端点都在正方形的边上。现在这个正方形的区域内有一个宝藏。问你从正方形外至少要开多少扇门才能到达宝藏的位置。

Solution: 线段相交,为什么呢,注意这句话,“这些墙的端点都在正方形的边上”,这就意味着墙会把正方形分成很多个封闭的小区域。以至于你必须跨过墙,而不能绕过墙。所以我们直接枚举正方形四条边上的点到宝藏点这条直线与所有墙的最小交点数。维护一个最小值就可以了。但是要注意的是,枚举的间隔为0.5,因为这是防止边上有相邻的断点,还有就是我把四条边都加到了墙的集合中,这样最后直接输出答案就可以了。

Code(JAVA):

import java.util.Scanner;

class Point {
double x, y;

public Point() {
}

public Point(double x, double y) {
this.x = x;
this.y = y;
}
}

class Line {
Point a, b;

public Line() {
}

public Line(Point a, Point b) {
this.a = a;
this.b = b;
}
}

public class Main {

Scanner cin = new Scanner(System.in);

int num_line;

Line[] lines = new Line[35];

Point src = new Point();

public Main() {
while (cin.hasNext()) {
num_line = cin.nextInt();

for (int i = 0; i < num_line; i++)
lines[i] = new Line(new Point(cin.nextDouble(),
cin.nextDouble()), new Point(cin.nextDouble(),
cin.nextDouble()));

lines[num_line++] = new Line(new Point(0, 0), new Point(0, 100));
lines[num_line++] = new Line(new Point(0, 0), new Point(100, 0));
lines[num_line++] = new Line(new Point(100, 100), new Point(0, 100));
lines[num_line++] = new Line(new Point(100, 100), new Point(100, 0));

src = new Point(cin.nextDouble(), cin.nextDouble());

int ans = 0x3f3f3f3f;

// 1
for (double i = 0.5; i < 100; i+=0.5) {
Line tmp = new Line(src, new Point(i, 0));
int sum = 0;
for (int j = 0; j < num_line; j++)
sum += segment_cross(tmp, lines[j]) ? 1 : 0;
ans = MIN(sum, ans);
}

// 2
for (double i = 0.5; i < 100; i+=0.5) {
Line tmp = new Line(src, new Point(100, i));
int sum = 0;
for (int j = 0; j < num_line; j++)
sum += segment_cross(tmp, lines[j]) ? 1 : 0;
ans = MIN(sum, ans);
}

// 3
for (double i = 0.5; i < 100; i+=0.5) {
Line tmp = new Line(src, new Point(i, 100));
int sum = 0;
for (int j = 0; j < num_line; j++)
sum += segment_cross(tmp, lines[j]) ? 1 : 0;
ans = MIN(sum, ans);
}

// 4
for (double i = 0.5; i < 100; i+=0.5) {
Line tmp = new Line(src, new Point(0, i));
int sum = 0;
for (int j = 0; j < num_line; j++)
sum += segment_cross(tmp, lines[j]) ? 1 : 0;
ans = MIN(sum, ans);
}

System.out.println("Number of doors = " + ans);
}
}

public static void main(String[] args) {
new Main();
}

double vector_product(Point a, Point b) {
return a.x * b.y - a.y * b.x;
}

Point get_vector(Point a, Point b) {
Point tmp = new Point();
tmp.x = b.x - a.x;
tmp.y = b.y - a.y;
return tmp;
}

double MIN(double x, double y) {
return x > y ? y : x;
}

double MAX(double x, double y) {
return x < y ? y : x;
}

int MIN(int x, int y) {
return x > y ? y : x;
}

boolean segment_cross(Line A, Line B) {
return (vector_product(get_vector(A.a, A.b), get_vector(A.a, B.a))
* vector_product(get_vector(A.a, A.b), get_vector(A.a, B.b)) <= 0
&& vector_product(get_vector(B.a, B.b), get_vector(B.a, A.a))
* vector_product(get_vector(B.a, B.b),
get_vector(B.a, A.b)) <= 0
&&

MIN(A.a.x, A.b.x) <= MAX(B.a.x, B.b.x)
&& MIN(B.a.x, B.b.x) <= MAX(A.a.x, A.b.x)
&& MIN(A.a.y, A.b.y) <= MAX(B.a.y, B.b.y) && MIN(B.a.y, B.b.y) <= MAX(
A.a.y, A.b.y));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: