POJ 1127 Jack Straws [计算几何]
2016-03-20 10:19
423 查看
2016年9月15日01:09:24更新
使用模板第二
使用模板第二
#include <cstdio> #include <cmath> #include <iostream> #include <cstring> using namespace std; //Template struct P { double x, y; P(double x = 0, double y = 0) : x(x), y(y) {} void read() { scanf("%lf%lf", &x, &y); } void print() { printf("%.6f %.6f", x, y); } }; typedef P V; V operator + (V a, V b) { return V(a.x+b.x, a.y+b.y); } V operator - (P a, P b) { return V(a.x-b.x, a.y-b.y); } V operator * (V a, double p) { return V(a.x*p, a.y*p); } V operator / (V a, double p) { return V(a.x/p, a.y/p); } const double eps = 1e-10; int dcmp(double x) { if (abs(x) < eps) return 0; else return x < 0 ? -1 : 1; } bool operator == (P a, P b) { return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; } double operator * (V a, V b) { return a.x*b.x + a.y*b.y; } double norm(V a) { return sqrt(a*a); } double det(V a, V b) { return a.x*b.y - a.y*b.x; } double angle(V a, V b) { return acos(a*b / norm(a) / norm(b)); } V rotate(V a, double rad) { return V(a.x*cos(rad) - a.y*sin(rad), a.x*sin(rad)+a.y*cos(rad)); } // P getLineIntersection(P p, V v, P q, V w) { V u = p - q; double t = det(w, u) / det(v, w); return p + v*t; } double ccw(P a, P b, P c) { return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y); } bool isParallel(P a1, P a2, P b1, P b2) { return dcmp(det(a1 - a2, b1 - b2)) == 0; } bool intersects(P a1, P a2, P b1, P b2) { if (ccw(a1, a2, b1) * ccw(a1, a2, b2) > 0) return false; if (ccw(b1, b2, a1) * ccw(b1, b2, a2) > 0) return false; return true; } bool onSeg(P q, P p1, P p2) { return dcmp(det(p1 - q, p2 - q)) == 0 && (p1 - q)*(p2 - q) <= 0; } bool isIntersect(P p1,P p2,P q1,P q2) { if(max(p1.x,p2.x)<min(q1.x,q2.x)||max(q1.x,q2.x)<min(p1.x,p2.x)||max(p1.y,p2.y)<min(q1.y,q2.y)||max(q1.y,q2.y)<min(p1.y,p2.y)) return 0; if(ccw(q1,q2,p1)*ccw 4000 (q1,q2,p2)<=0&&ccw(p1,p2,q1)*ccw(p1,p2,q2)<=0) return 1; else return 0; } //MAIN const int MAXN = 13; int n; P p[MAXN], q[MAXN]; bool g[MAXN][MAXN]; void solve() { for (int i = 0; i < n; i++) { p[i].read(); q[i].read(); } memset(g, 0, sizeof(g)); for (int i = 0; i < n; i++) { g[i][i] = true; for (int j = 0; j < i; j++) { if (isIntersect(p[i], q[i], p[j], q[j])) { g[i][j] = true; g[j][i] = true; } } } for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { g[i][j] |= (g[i][k] && g[k][j]); } } } for (int i = 0; ; i++) { int a, b; scanf("%d%d", &a, &b); if (a == 0 && b == 0) break; puts(g[a-1][b-1] ? "CONNECTED" : "NOT CONNECTED"); } } int main() { //freopen("in.txt", "r", stdin); for (;;) { scanf("%d", &n); if (n == 0) break; solve(); } }
Description
给n个线段,再个m个查询,问两个线段是否相连reference
《挑战程序设计竞赛(第二版)》Code
#include <cstdio> #include <cmath> #include <iostream> using namespace std; const int maxn = 13; const int maxm = 200; const double eps = 1e-10; int n; //考虑误差的加法 double add(const double &a, const double &b) { if (abs(a + b) < eps * (abs(a) + abs(b))) return 0; return a + b; } struct P { double x, y; //两个构造函数 必须都写 P() {} P(double x, double y) : x(x), y(y) {} //向量加法 P operator + (P p) { return P(add(x, p.x), add(y, p.y)); } //向量减法 P operator - (P p) { return P(add(x, -p.x), add(y, -p.y)); } //向量数乘 P operator * (double d) { return P(x * d, y * d); } //向量 dot x1*x2+y1*y2 double dot(P p) { return add(x * p.x, y * p.y); } //向量 det x1y2-x2y1 double det(P p) { return add(x * p.y, -y * p.x); } }; //判断点p是否在 线段p1-p2上 bool on_seg(P p1, P p2, P q) { return (p1 - q).det(p2 - q) == 0 && (p1 - q).dot(p2 - q) <= 0; } //求交点 P intersection(P p1, P p2, P q1, P q2) { return p1 + (p2 - p1) * ((q2 - q1).det(q1 - p1) / (q2 - q1).det(p2 - p1)); } void solve() { P p[maxn], q[maxn]; for (int i = 0; i < n; i++) { int x1, y1, x2, y2; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); p[i].x = x1; p[i].y = y1; q[i].x = x2; q[i].y = y2; } bool g[maxn][maxn] = {false}; for (int i = 0; i < n; i++) { g[i][i] = true; for (int j = 0; j < i; j++) //如果平行 if ((p[i] - q[i]).det(p[j] - q[j]) == 0) g[i][j] = g[j][i] = on_seg(p[i], q[i], p[j]) || on_seg(p[i], q[i], q[j]) || on_seg(p[j], q[j], p[i]) || on_seg(p[j], q[j], q[i]); else { //求交点 P r = intersection(p[i], q[i], p[j], q[j]); g[i][j] = g[j][i] = on_seg(p[i], q[i], r) && on_seg(p[j], q[j], r); } } //判断是否相连 for (int k = 0; k < n; k++) for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) g[i][j] |= g[i][k] && g[k][j]; for (int i = 0; ; i++) { int a, b; scanf("%d%d", &a, &b); if (a == 0 && b == 0) break; puts(g[a-1][b-1] ? "CONNECTED" : "NOT CONNECTED"); } } int main() { for(;;) { scanf("%d", &n); if (n == 0) break; solve(); } }
相关文章推荐
- leetcode 25. Reverse Nodes in k-Group
- Android App开发总结
- 第四周项目5:用递归方法求解(3)求两个数的最大公约数
- 查看git仓库是否有文件未提交
- 第三周学习进度
- SurfaceView有关
- 【机房合作】单例模式的实现(一)
- 初始化一个新的Git仓库
- openssl相关指令及生成私有证书
- HtmlParser基础教程
- UI中常用方法的调用时间
- Harvard architecture
- 中国电影电视奖项
- ExtJs之单选及多选框
- python---游戏登录
- HttpClient使用详解
- 15 API-集合(Collection(功能,迭代器),List(List特有迭代器,并发异常),常见数据结构图示(栈,队列,数组,链表))&对象数组
- Redis开源代码读书笔记五(adlist模块)
- 第4周项目5 返回Fibnacci序列中的第n个数
- 进入Docker容器