POJ 1127 Jack Straws [计算几何]

来源:互联网 发布:unity3d 字体描边 编辑:程序博客网 时间:2024/04/29 13:36

2016年9月15日01:09:24更新
使用模板第二

#include <cstdio>#include <cmath>#include <iostream>#include <cstring>using namespace std;//Templatestruct 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(q1,q2,p2)<=0&&ccw(p1,p2,q1)*ccw(p1,p2,q2)<=0)        return 1;    else        return 0;}//MAINconst 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();  }}
0 0