POJ1066
2016-04-19 23:13
225 查看
Problem: Treasure Hunt
Description: 一个正方形区域,里面有很多墙,这些墙的端点都在正方形的边上。现在这个正方形的区域内有一个宝藏。问你从正方形外至少要开多少扇门才能到达宝藏的位置。
Solution: 线段相交,为什么呢,注意这句话,“这些墙的端点都在正方形的边上”,这就意味着墙会把正方形分成很多个封闭的小区域。以至于你必须跨过墙,而不能绕过墙。所以我们直接枚举正方形四条边上的点到宝藏点这条直线与所有墙的最小交点数。维护一个最小值就可以了。但是要注意的是,枚举的间隔为0.5,因为这是防止边上有相邻的断点,还有就是我把四条边都加到了墙的集合中,这样最后直接输出答案就可以了。
Code(JAVA):
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)); } }
相关文章推荐
- 教师面试详细流程
- 响应式web设计
- Mac系统终端命令行不执行命令 总出现command not found解决方法
- ovs
- 使用正则表达式突出搜索结果
- Windows环境下利器:powershell
- 如何及时汇报反馈工作
- Java语言基础2
- SharePoint 轻量化应用之HR招聘系统之初试结果通知及复试面试通知表单
- Js中this用法及注意点详解
- Okhttp使用
- cmd连接mysql的方法详解
- 重学数据结构系列之——八大排序算法
- git clone远程库错误
- 即时刷新父窗体数据(调用父窗体的方法)
- hdoj 1559 最大子矩阵
- 关于应用权限的问题
- 用Eslipse开发Android案例(1)——计算器<part1>
- 用QT创建一个Windows Service以及踩到的若干坑
- 2016第17周二