zoukankan      html  css  js  c++  java
  • Find the Border UVALive

    Find the Border

     UVALive - 3218 

    题意: 给n个点连成的多边形,求边界.

    从左下角的点开始走,每次走需要右转最多的点. 类似卷包裹.

      1 /*************************************************************************
      2     > File Name: board.cpp
      3     > Author: yijiull
      4     > Mail: 1147161372@qq.com 
      5     > Created Time: 2017年09月23日 星期六 10时50分19秒
      6  ************************************************************************/
      7 #include <iostream>
      8 #include <cstring>
      9 #include <cstdio>
     10 #include <bits/stdc++.h>
     11 using namespace std;
     12 #define FP freopen("in.txt", "r", stdin)
     13 const double eps = 1e-9;
     14 const double pi = acos(-1.0);
     15 const int inf = 0x3f3f3f3f;
     16 struct Point {
     17     double x,y;
     18     Point (double x = 0, double y = 0) : x(x), y(y) {}
     19 };
     20 typedef Point Vector;
     21 Vector operator + (Vector a, Vector b) {
     22     return Vector (a.x + b.x, a.y + b.y);
     23 }
     24 Vector operator * (Vector a, double s) {
     25     return Vector (a.x * s, a.y * s);
     26 }
     27 Vector operator / (Vector a, double p) {
     28     return Vector (a.x / p, a.y / p);
     29 }
     30 Vector operator - (Point a, Point b) {
     31     return Vector (a.x - b.x, a.y - b.y);
     32 }
     33 bool operator < (Point a, Point b) {
     34     return a.x < b.x || (a.x == b.x && a.y < b.y);
     35 }
     36 int dcmp (double x) {
     37     if(fabs(x) < eps) return 0;
     38     return x < 0 ? -1 : 1;
     39 }
     40 bool operator == (const Point &a, const Point &b) {
     41     return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
     42 }
     43 double Dot(Vector a, Vector b) {
     44     return a.x * b.x + a.y * b.y;
     45 }
     46 double Length (Vector a) {
     47     return sqrt(Dot(a, a));
     48 }
     49 double Angle (Vector a) {
     50     return atan2(a.y, a.x);
     51 }
     52 double Cross (Vector a, Vector b) {
     53     return a.x * b.y - a.y * b.x;
     54 }
     55 //两直线交点
     56 Point GetLineIntersection (Point p, Vector v, Point q, Vector w) {
     57     Vector u = p - q;
     58     double t1 = Cross(w, u) / Cross(v, w);
     59     double t2 = Cross(v, u) / Cross(v, w);
     60     return p + v * t1;  //  return q + w * t2;
     61 }
     62 //判断两线段是否规范相交
     63 bool SegmentProperIntersection(Point a1, Point b1, Point a2, Point b2) { 
     64     double c1 = Cross(b1 - a1, a2 - a1), c2 = Cross(b1 - a1, b2 - a1),
     65            c3 = Cross(b2 - a2, a1 - a2), c4 = Cross(b2 - a2, b1 - a2);
     66     return dcmp(c1)*dcmp(c2) < 0 && dcmp(c3)*dcmp(c4) < 0;
     67 }
     68 //判断点是否在线段上(即∠PAB等于π)
     69 bool OnSegment(Point p, Point a, Point b) {
     70     return dcmp(Cross(a - p, b - p)) == 0 && dcmp(Dot(a - p, b - p)) < 0;
     71 }
     72 const int maxn = 1010;
     73 Point p[maxn], res[maxn], temp[maxn];
     74 double ang[maxn], s;
     75 int cnt;
     76 void add(Point a, Point b) {
     77     temp[cnt] = a;
     78     ang[cnt] = atan2(a.y - b.y, a.x - b.x) - s;
     79     while(dcmp(ang[cnt]) <= 0) ang[cnt] += 2*pi;
     80     cnt++;
     81 }
     82 int main(){
     83     int n;
     84     //FP;
     85     while(scanf("%d", &n) != EOF) {
     86         int fg = 0;
     87         for(int i = 0; i < n; i++) {
     88             scanf("%lf%lf", &p[i].x, &p[i].y);
     89             if(p[i] < p[fg]) fg = i;
     90         }
     91         res[0] = p[fg];
     92         int num = 1;
     93         s = -pi;
     94         while (1) {
     95             cnt = 0;
     96             for (int i = 0; i < n; i++) {
     97                 if (res[num - 1] == p[i]) {
     98                     add(p[(i + 1) % n], res[num - 1]);
     99                     add(p[(i + n - 1) % n], res[num - 1]);
    100                     break;
    101                 }
    102             }
    103             for (int i = 0; i < n; i++) {
    104                 if (OnSegment(res[num - 1], p[i], p[(i + 1) % n])) {
    105                     add(p[(i + 1) % n], res[num - 1]);
    106                     add(p[i], res[num - 1]);
    107                 }
    108             }
    109             int id = 0;
    110             for (int i = 0; i < cnt; i++)
    111                 if (ang[i] < ang[id])
    112                     id = i;
    113             double minlen = 1e9;
    114             Point RP = temp[id], its;
    115             for (int i = 0; i < n; i++) {
    116                 if (SegmentProperIntersection(temp[id], res[num - 1], p[i], p[(i + 1) % n])) {
    117                     its = GetLineIntersection(temp[id], temp[id] - res[num - 1], p[i], p[i] - p[(i + 1) % n]);
    118                     if (Length(its - res[num - 1]) < minlen) {
    119                         minlen = Length(its - res[num - 1]);
    120                         RP = its;
    121                     }
    122                 }
    123             }
    124             res[num] = RP;
    125             s = atan2(res[num - 1].y - res[num].y, res[num - 1].x - res[num].x);
    126             num++;
    127             if (res[num - 1] == res[0])
    128                 break;
    129         }
    130         printf("%d
    ", num - 1);
    131         for(int i = 0; i< num-1; i++) 
    132             printf("%.4lf %.4lf
    ",res[i].x,res[i].y);
    133     }
    134     return 0;
    135 }
    View Code
  • 相关阅读:
    windows下查看端口进程占用情况
    分布式文件管理系统MooseFS在centOS 7中的安装
    开发中的技术选型调研总结
    windows和linux无法访问VMware中linux的tomcat主页问题
    如何使windows系统ping通VMware下面的linux系统
    VMware中linux安装jdk
    mysql数据库之存储过程入门
    Hibernate批处理操作优化 (批量插入、更新与删除)
    JDBC: 批量处理提高SQL处理速度
    小程序 长按复制文本
  • 原文地址:https://www.cnblogs.com/yijiull/p/7583288.html
Copyright © 2011-2022 走看看