zoukankan      html  css  js  c++  java
  • uvalive 4728 Squares

    题意:求所有正方形中两点距离最大值的平方值。

    思路:旋转卡壳法。

    分别用数组和vector存凸包时,旋转卡壳代码有所不同。

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<iostream>
      6 #include<memory.h>
      7 #include<cstdlib>
      8 #include<vector>
      9 #define clc(a,b) memset(a,b,sizeof(a))
     10 #define LL long long int
     11 #define up(i,x,y) for(i=x;i<=y;i++)
     12 #define w(a) while(a)
     13 using namespace std;
     14 const double inf=0x3f3f3f3f;
     15 const int N = 4010;
     16 const double eps = 5*1e-13;
     17 const double PI = acos(-1.0);
     18 using namespace std;
     19 
     20 struct Point
     21 {
     22     int x, y;
     23     Point(int x=0, int y=0):x(x),y(y) { }
     24 };
     25 
     26 typedef Point Vector;
     27 
     28 Vector operator - (const Point& A, const Point& B)
     29 {
     30     return Vector(A.x-B.x, A.y-B.y);
     31 }
     32 
     33 int Cross(const Vector& A, const Vector& B)
     34 {
     35     return A.x*B.y - A.y*B.x;
     36 }
     37 
     38 int Dot(const Vector& A, const Vector& B)
     39 {
     40     return A.x*B.x + A.y*B.y;
     41 }
     42 
     43 int Dist2(const Point& A, const Point& B)
     44 {
     45     return (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y);
     46 }
     47 
     48 bool operator < (const Point& p1, const Point& p2)
     49 {
     50     return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
     51 }
     52 
     53 bool operator == (const Point& p1, const Point& p2)
     54 {
     55     return p1.x == p2.x && p1.y == p2.y;
     56 }
     57 
     58 // 点集凸包
     59 // 如果不希望在凸包的边上有输入点,把两个 <= 改成 <
     60 // 注意:输入点集会被修改
     61 vector<Point> ConvexHull(vector<Point>& p)
     62 {
     63     // 预处理,删除重复点
     64     sort(p.begin(), p.end());
     65     p.erase(unique(p.begin(), p.end()), p.end());
     66 
     67     int n = p.size();
     68     int m = 0;
     69     vector<Point> ch(n+1);
     70     for(int i = 0; i < n; i++)
     71     {
     72         while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
     73         ch[m++] = p[i];
     74     }
     75     int k = m;
     76     for(int i = n-2; i >= 0; i--)
     77     {
     78         while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
     79         ch[m++] = p[i];
     80     }
     81     if(n > 1) m--;
     82     ch.resize(m);
     83     return ch;
     84 }
     85 
     86 // 返回点集直径的平方
     87 int diameter2(vector<Point>& points)
     88 {
     89     vector<Point> p = ConvexHull(points);
     90     int n = p.size();
     91     if(n == 1) return 0;
     92     if(n == 2) return Dist2(p[0], p[1]);
     93     p.push_back(p[0]); // 免得取模
     94     int ans = 0;
     95     for(int u = 0, v = 1; u < n; u++)
     96     {
     97         // 一条直线贴住边p[u]-p[u+1]
     98         for(;;)
     99         {
    100             // 当Area(p[u], p[u+1], p[v+1]) <= Area(p[u], p[u+1], p[v])时停止旋转
    101             // 即Cross(p[u+1]-p[u], p[v+1]-p[u]) - Cross(p[u+1]-p[u], p[v]-p[u]) <= 0
    102             // 根据Cross(A,B) - Cross(A,C) = Cross(A,B-C)
    103             // 化简得Cross(p[u+1]-p[u], p[v+1]-p[v]) <= 0
    104             int diff = Cross(p[u+1]-p[u], p[v+1]-p[v]);
    105             if(diff <= 0)
    106             {
    107                 ans = max(ans, Dist2(p[u], p[v])); // u和v是对踵点
    108                 if(diff == 0) ans = max(ans, Dist2(p[u], p[v+1])); // diff == 0时u和v+1也是对踵点
    109                 break;
    110             }
    111             v = (v + 1) % n;
    112         }
    113     }
    114     return ans;
    115 }
    116 
    117 int main()
    118 {
    119     int T;
    120     scanf("%d", &T);
    121     while(T--)
    122     {
    123         int n;
    124         scanf("%d", &n);
    125         vector<Point> points;
    126         for(int i = 0; i < n; i++)
    127         {
    128             int x, y, w;
    129             scanf("%d%d%d", &x, &y, &w);
    130             points.push_back(Point(x, y));
    131             points.push_back(Point(x+w, y));
    132             points.push_back(Point(x, y+w));
    133             points.push_back(Point(x+w, y+w));
    134         }
    135         printf("%d
    ", diameter2(points));
    136     }
    137     return 0;
    138 }
    View Code
  • 相关阅读:
    JavaScript-警告(alert 消息对话框)
    JavaScript中4种document.write()输出展示
    JavaScript-什么是函数
    JavaScript-判断语句(if...else)
    javascript里面什么是变量
    [学习笔记] IT项目管理
    [学习笔记] IT项目管理
    [学习笔记] Oracle基础增删改查用法
    [学习笔记] Oracle字段类型、建表语句、添加约束
    [学习笔记] RabbitMQ的简单使用
  • 原文地址:https://www.cnblogs.com/ITUPC/p/4887311.html
Copyright © 2011-2022 走看看