poj 1912 A highway and the seven dwarfs
| Time Limit: 8000MS | Memory Limit: 30000K | |
| Total Submissions: 2622 | Accepted: 535 | |
| Case Time Limit: 3000MS | ||
Description
Once, the humans living in countries around Dwarfland decided to build several straight highways. As the humans weren't aware of the dwarfs, some of the planned highways passed through Dwarfland. The dwarfs discovered this and were quite unhappy about it. The dwarfs are very little, and also very slow, so they are unable to cross the highway safely.
The dwarfs managed to get the plans for the highways somehow, and now they need your help. They would like to keep on visiting each other, so they don't like those highways which divide their houses into two non-empty parts. After they find out which highways they don't like, they will magically prevent the humans from building them.
The dwarfs are very little, and cannot reach the keyboard. So they asked for your help.
Task
Given is a number N of points (houses) in the plane and several straight lines (highways). For each given line, your task is to determine whether all N points lie on the same side of the line or not. Your program has to output the answer for the currently processed line before reading the description of the next one. You may assume that no highway passes through any of the houses.
Input
Each of the following lines contains four real numbers X1, Y1, X2, Y2 ( -109 < = X1, Y1, X2, Y2 < = 109) separated by a single space. These numbers are the coordinates of two different points [X1, Y1] and [X2, Y2], lying on the highway.
Output
Sample Input
4
0.0 0
6.00 -0.001
3.125 4.747
4.747 0.47
5 3 7 0
4 -4.7 7 4.7
4 47 4 94
Sample Output
GOOD
BAD
BAD
Hint

第一幅图中,向量AE,ED,DC,CB,BA的极角在 坐标系中变化是单调的,于是把他们都移到图二中来,都以O点为起点,按照极角大小排序并编号,凸包的算法因人而异,我现在用的凸包算法是以最左端的A点开始存储,并按照逆时针方向存储点的,那么AE向量最好标记为极角最小的向量,ED次之,以此类推,那么我们就得设定极角的变化范围为(-90,270],这样将所有的向量排好序,并标记好编号,譬如右图的1向量代表AE向量。。。现在又给出一条直线L1,如何得知L1和凸包相交呢?我们平移L1的向量形式,移到L1只割掉了凸包一个点的位置(一共两个位置),L2的方向为p1p2,L3的方向为p2p1,我们发现这两条向量如果都要逆时针转一个方向,分别转动到向量DC和向量BA的位置需要转动的角度是最小的,而向量DC和BA的端点D,B又恰恰是向量L3和L1所割掉的点那么如果线段DB和直线L1有交点,则L1一定和凸包存在交点的。这个规律放到图二来看,直线L的向量形式为p2p1,转到向量3是所转角度最小的,其反向的向量转到向量5转角度又是最小的,向量3与向量5都是可以通过二分查找找出来,找到向量之后在取其起始端点,判断这两个起始端点是否与直线相交。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<string>
#include<functional>
#include<cmath>
#include<stack>
using namespace std;
const int N_MAX = + ;
#define INF 0x3f3f3f3f
#define EPS 1e-10
#define equals(a,b) (fabs(a-b)<EPS)
#define pi acos(-1.0)
#define BOTTOM 0
#define LEFT 1
#define RIGHT 2
#define TOP 3 static const int COUNTER_CLOCKWISE = -;
static const int CLOCKWISE = ;
static const int ONLINE_BACK = ;
static const int ONLINE_FRONT = -;
static const int ON_SEGMENT = ; double add(double a,double b) {
if (abs(a + b) < EPS*(abs(a) + abs(b)))return ;
return a + b;
} class point {
public:
double x, y;
point(double x = , double y = ) :x(x), y(y) {}
point operator +(point p) { return point(x+p.x, y+p.y); }
point operator -(point p) { return point(x - p.x,y - p.y); }
point operator *(double a) { return point(a*x, a*y); }
point operator /(double a) { return point(x / a, y / a); }
double norm() { return x*x + y*y; }
double abs() { return sqrt(norm()); }
bool operator<(const point&p)const {
return x != p.x ? x < p.x : y < p.y;
}
bool operator ==(const point&p)const {
return x == p.x && y == p.y;
}
double dot(point p) {
return x*p.x+y*p.y;
}
double det(point p) {
return x*p.y- y*p.x;
}
}; struct Segment {
point p1, p2;
Segment(point p1 = point(), point p2 = point()) :p1(p1), p2(p2) {}
};
typedef Segment line; typedef vector<point>Polygon;
//????????????p0p1?????????p0p2????????¬??????
int ccw(point p0, point p1, point p2) {
point a = p1 - p0;
point b = p2 - p0;
if (a.det(b) > EPS)return COUNTER_CLOCKWISE;
if (a.det(b) < -EPS)return CLOCKWISE;
if (a.dot(b) < -EPS)return ONLINE_BACK;
if (a.norm() >= b.norm())return ON_SEGMENT;//!!
return ONLINE_FRONT;
}
//????????????p1p2???p3p4????????????
bool intersect(point p1, point p2, point p3, point p4) {
return (ccw(p1, p2, p3)*ccw(p1, p2, p4) < &&
ccw(p3, p4, p1)*ccw(p3, p4, p2) < );//!!!!!!!!!!!!!!!!!!!!!!!!!!!
} inline double normalize(double r)
{
if (r < -pi / 2.0 + EPS) r += pi * ;
return r;
} double arg(const point& p) { return normalize(atan2(p.y, p.x)); }
inline bool double_cmp(double a,double b) {
return a + EPS < b;
} ////
typedef vector<point>Polygon; vector<point> convex_hull(point *ps, int N)
{
sort(ps, ps + N);
int k = ; // 凸包的顶点数
vector<point> qs(N * ); // 构造中的凸包
// 构造凸包的下侧
for (int i = ; i < N; ++i)
{
while (k > && (qs[k - ] - qs[k - ]).det(ps[i] - qs[k - ]) <= ) --k;
qs[k++] = ps[i];
}
// 构造凸包的上侧
for (int i = N - , t = k; i >= ; --i)
{
while (k > t && (qs[k - ] - qs[k - ]).det(ps[i] - qs[k - ]) <= ) --k;
qs[k++] = ps[i];
}
qs.resize(k - );
return qs;
} point s[N_MAX];
int n;
double a[N_MAX];//记录凸包每条边行成的向量倾斜度
int main() {
scanf("%d", &n);
for (int i = ; i < n; i++) {
scanf("%lf%lf", &s[i].x, &s[i].y);
}
int N;
Polygon con;
if (n > ) { con=convex_hull(s,n);
N = con.size();
con.push_back(con[]);
}
for (int i = ; i <N; i++) {
a[i] = arg(con[i + ] - con[i]);
} sort(a, a + N, double_cmp);
point p1, p2;
while (scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y)!=EOF) {
if (n < ) { puts("GOOD"); continue; }
int i = upper_bound(a, a + N, arg(p2 - p1), double_cmp) - a;
int j = upper_bound(a, a + N, arg(p1 - p2), double_cmp) - a;
puts((((p2 - p1).det(con[i] - p1) * (p2 - p1).det(con[j] - p1) > -EPS)) ? "GOOD" : "BAD"); } return ;
}
poj 1912 A highway and the seven dwarfs的更多相关文章
- POJ 1912 A highway and the seven dwarfs (凸包)
[题目链接] http://poj.org/problem?id=1912 [题目大意] 给出一些点,表示一些屋子,这些屋子共同组成了村庄,现在要建一些高速公路 问是否经过了村庄. [题解] 这些屋子 ...
- POJ1912 A highway and the seven dwarfs (判断凸包与直线相交 logn)
POJ1912 给定n个点 和若干条直线,判断对于一条直线,是否存在两个点在直线的两侧. 显然原命题等价于 凸包与直线是否相交. O(n)的算法是显而易见的 但是直线数量太多 就会复杂到O(n^2)由 ...
- POJ 1912 凸包
题目: #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib& ...
- POJ 2485 Highway(Prim+邻接矩阵)
( ̄▽ ̄)" //求最短总路径中的最大边长,Prim还需要一个Max变量 #include<iostream> #include<cstdio> #include&l ...
- poj 2485 Highways
题目连接 http://poj.org/problem?id=2485 Highways Description The island nation of Flatopia is perfectly ...
- POJ 1751 Highways (最小生成树)
Highways Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit Sta ...
- POJ 1751 Highways (最小生成树)
Highways 题目链接: http://acm.hust.edu.cn/vjudge/contest/124434#problem/G Description The island nation ...
- 【POJ 2152】 Fire (树形DP)
Fire Description Country Z has N cities, which are numbered from 1 to N. Cities are connected by h ...
- Highways poj 2485
Description The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has no public h ...
随机推荐
- Mysql 8.0 新特性
转载:https://www.jianshu.com/p/be29467c2b0c
- RabbitMQ Server的安装、配置及常用命令
首先需要安装Erlang环境: http://www.rabbitmq.com/server.html 下载RabbitMQ Server的windows安装包并安装到D盘下: http://www. ...
- java String中的replace(oldChar,newChar) replace(CharSequence target,CharSequence replacement) replaceAll replaceFirst 面试题:输入英文语句,单词首字符大写后输出 char String int 相互转换
package com.swift; import java.util.Scanner; public class FirstChat_ToCaps_Test { public static void ...
- 接口的定义——默认加public abstract默认全局常量;与继承不同,子类可以同时实现多个接口;抽象类实现接口;接口继承接口
一. 接口的定义 接口中定义的方法,全部都为抽象方法,默认加public abstract 接口中定义的变量,全部为全局常量,默认加public static final 二.与继承不同,子类可以同时 ...
- 修改broadcom 4322无线网卡ID教程,不再显示第三方无线网卡
本帖最后由 hellokingabc 于 2016-1-11 03:07 编辑 黑苹果已经基本完美,但是无线网卡总是出现问题,经常断网,经过搜索,原因在于无线网卡在OSX系统下显示为第三方无线网卡,只 ...
- codis 配置
#修改dashboard.toml: coordinator_name = "zookeeper" coordinator_addr = "192.168.56.101: ...
- Laravel核心解读--Console内核
Console内核 上一篇文章我们介绍了Laravel的HTTP内核,详细概述了网络请求从进入应用到应用处理完请求返回HTTP响应整个生命周期中HTTP内核是如何调动Laravel各个核心组件来完成任 ...
- 【php】【趣味代码】对象引用的比较
<?php $a = new stdClass(); $a->name = 'flint'; $b = $a ; $b->sex = 'man'; saveObject($b); f ...
- 多线程辅助类之CountDownLatch(三)
CountDownLatch信号灯是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待.它可以实现多线程的同步互斥功能,和wait和notify方法实现功能类似,具体 ...
- 创建Django项目并将其部署在腾讯云上
这段时间在做scrapy爬虫,对爬出来的数据基于Django做了统计与可视化,本想部署在腾讯云上玩玩,但是因为以前没有经验遇到了一些问题,在这里记录一下: 首先说下Django的创建与配置: 1. 创 ...