题目传送门

题意:一个矩形和一条线段,问是否有相交

分析:考虑各种情况。坑点:给出的矩形的两个端点是无序的,还有线段完全在矩形内也算相交

/************************************************
* Author :Running_Time
* Created Time :2015/10/27 星期二 13:17:49
* File Name :POJ_1410.cpp
************************************************/ #include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-10;
const double PI = acos (-1.0);
int dcmp(double x) { //三态函数,减少精度问题
if (fabs (x) < EPS) return 0;
else return x < 0 ? -1 : 1;
}
struct Point { //点的定义
double x, y;
Point (double x=0, double y=0) : x (x), y (y) {}
Point operator + (const Point &r) const { //向量加法
return Point (x + r.x, y + r.y);
}
Point operator - (const Point &r) const { //向量减法
return Point (x - r.x, y - r.y);
}
Point operator * (double p) { //向量乘以标量
return Point (x * p, y * p);
}
Point operator / (double p) { //向量除以标量
return Point (x / p, y / p);
}
bool operator < (const Point &r) const { //点的坐标排序
return x < r.x || (x == r.x && y < r.y);
}
bool operator == (const Point &r) const { //判断同一个点
return dcmp (x - r.x) == 0 && dcmp (y - r.y) == 0;
}
};
typedef Point Vector; //向量的定义
Point read_point(void) { //点的读入
double x, y;
scanf ("%lf%lf", &x, &y);
return Point (x, y);
}
double dot(Vector A, Vector B) { //向量点积
return A.x * B.x + A.y * B.y;
}
double cross(Vector A, Vector B) { //向量叉积
return A.x * B.y - A.y * B.x;
}
double polar_angle(Vector A) { //向量极角
return atan2 (A.y, A.x);
}
double length(Vector A) { //向量长度,点积
return sqrt (dot (A, A));
}
double angle(Vector A, Vector B) { //向量转角,逆时针,点积
return acos (dot (A, B) / length (A) / length (B));
}
Vector rotate(Vector A, double rad) { //向量旋转,逆时针
return Vector (A.x * cos (rad) - A.y * sin (rad), A.x * sin (rad) + A.y * cos (rad));
}
Vector nomal(Vector A) { //向量的单位法向量
double len = length (A);
return Vector (-A.y / len, A.x / len);
}
Point line_line_inter(Point p, Vector V, Point q, Vector W) { //两直线交点,参数方程
Vector U = p - q;
double t = cross (W, U) / cross (V, W);
return p + V * t;
}
double point_to_line(Point p, Point a, Point b) { //点到直线的距离,两点式
Vector V1 = b - a, V2 = p - a;
return fabs (cross (V1, V2)) / length (V1);
}
double point_to_seg(Point p, Point a, Point b) { //点到线段的距离,两点式
if (a == b) return length (p - a);
Vector V1 = b - a, V2 = p - a, V3 = p - b;
if (dcmp (dot (V1, V2)) < 0) return length (V2);
else if (dcmp (dot (V1, V3)) > 0) return length (V3);
else return fabs (cross (V1, V2)) / length (V1);
}
Point point_line_proj(Point p, Point a, Point b) { //点在直线上的投影,两点式
Vector V = b - a;
return a + V * (dot (V, p - a) / dot (V, V));
}
bool can_inter(Point a1, Point a2, Point b1, Point b2) { //判断线段相交,两点式
double c1 = cross (a2 - a1, b1 - a1), c2 = cross (a2 - a1, b2 - a1),
c3 = cross (b2 - b1, a1 - b1), c4 = cross (b2 - b1, a2 - b1);
return dcmp (c1) * dcmp (c2) < 0 && dcmp (c3) * dcmp (c4) < 0;
}
bool on_seg(Point p, Point a1, Point a2) { //判断点在线段上,两点式
return dcmp (cross (a1 - p, a2 - p)) == 0 && dcmp (dot (a1 - p, a2 - p)) < 0;
}
double area_triangle(Point a, Point b, Point c) { //三角形面积,叉积
return fabs (cross (b - a, c - a)) / 2.0;
}
double area_poly(Point *p, int n) { //多边形面积,叉积
double ret = 0;
for (int i=1; i<n-1; ++i) {
ret += fabs (cross (p[i] - p[0], p[i+1] - p[0]));
}
return ret / 2;
}
/*
点集凸包
*/
vector<Point> convex_hull(vector<Point> &P) {
sort (P.begin (), P.end ());
int n = P.size (), k = 0;
vector<Point> ret (n * 2);
for (int i=0; i<n; ++i) {
while (k > 1 && cross (ret[k-1] - ret[k-2], P[i] - ret[k-1]) <= 0) k--;
ret[k++] = P[i];
}
for (int i=n-2, t=k; i>=0; --i) {
while (k > t && cross (ret[k-1] - ret[k-2], P[i] - ret[k-1]) <= 0) k--;
ret[k++] = P[i];
}
ret.resize (k-1);
return ret;
} struct Circle {
Point c;
double r;
Circle () {}
Circle (Point c, double r) : c (c), r (r) {}
Point point(double a) {
return Point (c.x + cos (a) * r, c.y + sin (a) * r);
}
};
struct Line {
Point p;
Vector v;
double r;
Line () {}
Line (const Point &p, const Vector &v) : p (p), v (v) {
r = polar_angle (v);
}
Point point(double a) {
return p + v * a;
}
};
/*
直线相交求交点,返回交点个数,交点保存在P中
*/
int line_cir_inter(Line L, Circle C, double &t1, double &t2, vector<Point> &P) {
double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;
double e = a * a + c * c, f = 2 * (a * b + c * d), g = b * b + d * d - C.r * C.r;
double delta = f * f - 4 * e * g;
if (dcmp (delta) < 0) return 0;
if (dcmp (delta) == 0) {
t1 = t2 = -f / (2 * e); P.push_back (L.point (t1));
return -1;
}
t1 = (-f - sqrt (delta)) / (2 * e); P.push_back (L.point (t1));
t2 = (-f + sqrt (delta)) / (2 * e); P.push_back (L.point (t2));
if (dcmp (t1) < 0 || dcmp (t2) < 0) return 0;
return 2;
} /*
两圆相交求交点,返回交点个数。交点保存在P中
*/
int cir_cir_inter(Circle C1, Circle C2, vector<Point> &P) {
double d = length (C1.c - C2.c);
if (dcmp (d) == 0) {
if (dcmp (C1.r - C2.r) == 0) return -1; //两圆重叠
else return 0;
}
if (dcmp (C1.r + C2.r - d) < 0) return 0;
if (dcmp (fabs (C1.r - C2.r) - d) < 0) return 0;
double a = polar_angle (C2.c - C1.c);
double da = acos ((C1.r * C1.r + d * d - C2.r * C2.r) / (2 * C1.r * d)); //C1C2到C1P1的角?
Point p1 = C1.point (a - da), p2 = C2.point (a + da);
P.push_back (p1);
if (p1 == p2) return 1;
else P.push_back (p2);
return 2;
}
/*
过点到圆的切线,返回切线条数,切线保存在V中
*/
int point_cir_tan(Point p, Circle C, Vector *V) {
Vector u = C.c - p;
double dis = length (u);
if (dis < C.r) return 0;
else if (dcmp (dis - C.r) == 0) {
V[0] = rotate (u, PI / 2); return 1;
}
else {
double ang = asin (C.r / dis);
V[0] = rotate (u, -ang);
V[1] = rotate (u, +ang);
return 0;
}
} Point s, e, lt, rb, rt, lb; int main(void) {
int n; scanf ("%d", &n);
while (n--) {
s = read_point ();
e = read_point ();
int x1, y1, x2, y2;
scanf ("%d%d%d%d", &x1, &y1, &x2, &y2);
if (x1 > x2) swap (x1, x2);
if (y1 < y2) swap (y1, y2);
lt = Point (x1, y1);
rb = Point (x2, y2);
rt = Point (rb.x, lt.y);
lb = Point (lt.x, rb.y);
bool flag = false;
if (on_seg (lt, s, e)) flag = true;
else if (on_seg (rt, s, e)) flag = true;
else if (on_seg (lb, s, e)) flag = true;
else if (on_seg (rb, s, e)) flag = true;
else if (can_inter (s, e, lt, rt)) flag = true;
else if (can_inter (s, e, rt, rb)) flag = true;
else if (can_inter (s, e, rb, lb)) flag = true;
else if (can_inter (s, e, lb, lt)) flag = true;
else if (dcmp (s.x - e.x) == 0 || dcmp (s.y - e.y) == 0) {
if (dcmp (s.x - e.x) == 0) {
if (dcmp (s.x - lt.x) == 0 || dcmp (s.x - rb.x) == 0) {
if (dcmp (max (s.y, e.y) - lt.y) <= 0 && dcmp (min (s.y, e.y) - rb.y) >= 0) flag = true;
}
}
else {
if (dcmp (s.y - lt.y) == 0 || dcmp (s.y - rb.y) == 0) {
if (dcmp (max (s.x, e.x) - rb.x) <= 0 && dcmp (min (s.x, e.x) - lb.x) >= 0) flag = true;
}
}
}
x1 = min (s.x, e.x); x2 = max (s.x, e.x);
y1 = min (s.y, e.y); y2 = max (s.y, e.y);
if (dcmp (x1 - lt.x) >= 0 && dcmp (x2 - rt.x) <= 0
&& dcmp (y1 - rb.y) >= 0 && dcmp (y2 - rt.y) <= 0) flag = true; puts (flag ? "T" : "F");
} //cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n"; return 0;
}

  

简单几何(线段相交) POJ 1410 Intersection的更多相关文章

  1. 简单几何(线段相交) POJ 2653 Pick-up sticks

    题目传送门 题意:就是小时候玩的一种游戏,问有多少线段盖在最上面 分析:简单线段相交,队列维护当前最上的线段 /******************************************** ...

  2. 简单几何(线段相交) POJ 1066 Treasure Hunt

    题目传送门 题意:从四面任意点出发,有若干障碍门,问最少要轰掉几扇门才能到达终点 分析:枚举入口点,也就是线段的两个端点,然后选取与其他线段相交点数最少的 + 1就是答案.特判一下n == 0的时候 ...

  3. 简单几何(线段相交) POJ 2826 An Easy Problem?!

    题目传送门 题意:两条线段看成两块木板,雨水从上方往下垂直落下,问能接受到的水的体积 分析:恶心的分类讨论题,考虑各种情况,尤其是入口被堵住的情况,我的方法是先判断最高的两个点是否在交点的同一侧,然后 ...

  4. 简单几何(线段相交)+模拟 POJ 3449 Geometric Shapes

    题目传送门 题意:给了若干个图形,问每个图形与哪些图形相交 分析:题目说白了就是处理出每个图形的线段,然后判断是否相交.但是读入输出巨恶心,就是个模拟题加上线段相交的判断,我第一次WA不知道输出要按字 ...

  5. 简单几何(线段相交+最短路) POJ 1556 The Doors

    题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...

  6. 简单几何(线段覆盖) POJ 3347 Kadj Squares

    题目传送门 题意:告诉每个矩形的边长,它们是紧贴着的,问从上往下看,有几个还能看到. 分析:用网上猥琐的方法,将边长看成左端点到中心的距离,这样可以避免精度问题.然后先求出每个矩形的左右端点,然后如果 ...

  7. 线段和矩形相交 POJ 1410

    // 线段和矩形相交 POJ 1410 // #include <bits/stdc++.h> #include <iostream> #include <cstdio& ...

  8. 线段相交 poj 1066

    // 线段相交 poj 1066 // 思路:直接枚举每个端点和终点连成线段,判断和剩下的线段相交个数 // #include <bits/stdc++.h> #include <i ...

  9. 线段相交 POJ 2653

    // 线段相交 POJ 2653 // 思路:数据比较水,据说n^2也可以过 // 我是每次枚举线段,和最上面的线段比较 // O(n*m) // #include <bits/stdc++.h ...

随机推荐

  1. 微信智慧KTV上线 不怕周末订不到包厢了

    周末邀三五好友唱唱歌是件惬意的事,可订包厢是个烦心事,总是people mountain people sea,而且价格比平时高出不少.现在好了,微信智慧KTV上线了,将有效解决传统KTV收银时间集中 ...

  2. Ubuntu 16.04 下安装Firefox的Flash插件

    在ubuntu系统环境下面打开优酷视频,发现无法播放视频.Adobe Flash Player 是一款轻量级浏览器插件,具有丰富的 Internet 应用运行时间,提供持续的迷人用户体验.绝妙的音频/ ...

  3. 纹理缓存(Texture Cache)

    纹理缓存是将纹理缓存起来方便之后的绘制工作.每一个缓存的图像的大小,颜色和区域范围都是可以被修改的.这些信息都是存储在内存中的,不用在每一次绘制的时候都发送给GPU. CCTextureCache C ...

  4. poj2240最短路 floyd

    Arbitrage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17360   Accepted: 7308 Descri ...

  5. HDOJ 1022 模拟栈

    Train Problem I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  6. ubuntu 修改保存报错E37:No write since last change(add ! to override)的解决方法

    报错信息如下: E37: No write since last change (add ! to override) 解决办法是: 在修改完后,将命令 :q 改成 :wq 即可.

  7. How to Configure Nginx for Optimized Performance

    Features Pricing Add-ons Resources | Log in Sign up   Guides & Tutorials Web Server Guides Nginx ...

  8. 【leetcode】Best Time to Buy and Sell Stock III

    Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the price of ...

  9. python 异常类型

    1.NameError:尝试访问一个未申明的变量>>>  vNameError: name 'v' is not defined 2.ZeroDivisionError:除数为0&g ...

  10. Emblog 备忘

    emblog换后台:(如admin-->xx) 1.xx目录下的globals.php打开找到替换admin(1) 2.www目录下的t\index.php 中找到替换admin(1) 3.ww ...