• 寻找最远点对(凸包求解)


    题目来源:https://biancheng.love/contest/41/problem/B/index

    寻找最远点对

    题目描述

    TD走廊里有一关“勇闯梅花桩”,水面上稀稀落落地立着几根柱子。Nova君自认为轻功不错,觉得可以在任意两根柱子之间跳跃,现在他想挑战一次跨越距离最远的两根柱子。请问,最远距离是多少?(由于木桩以横纵坐标形式给出,为了计算方便,避免求平方根,答案只需给出距离的平方即可)

    输入

    多组测试数据(组数不超过10),对于每组数据,第一行为一个正整数N,代表梅花桩的个数,接下来N行,每行两个正整数xi, yi分别代表第 i 根桩子的横纵坐标。 (数据在INT范围内)

    输出

    对于每组数据,输出一行,为距离最远的两根柱子的距离的平方。

    输入样例

    3
    1 1
    1 2
    0 0

    输出样例

    5

    解题思路:
    求出最远的点对,可以化为求出对应的凸包上最远的两个点。

    平面凸包 :

     定义: 对一个简单多边形来说,如果给定其边界上或内部的任意两个点,连接这两个点的线段上的所有点都被包含在该多边形的边界上或内部的话,则该多边形为凸多边形 。

    在解决平面凸包下面介绍了两种算法:

    一、  Graham扫描法,运行时间为O(nlgn)。

    二、  Jarvis步进法,运行时间为O(nh),h为凸包中的顶点数。


    推荐博客http://blog.csdn.net/bone_ace/article/details/46239187
    推荐博客http://www.cnblogs.com/jbelial/archive/2011/08/05/2128625.html
    给出代码:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #define INF -110
     5 
     6 using namespace std;
     7 long long i,j,k,n,top,ans;
     8 
     9 struct Node
    10 {
    11  int x;
    12  int y;
    13 }no[1000010],stack[1000010];
    14 
    15 long long dis(Node p1,Node p2)
    16 {
    17     return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
    18 }
    19 
    20 long long mult(Node p1,Node p2,Node p0)
    21 {
    22     return ((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
    23 }
    24 
    25 long long cmp(Node a,Node b)
    26 {
    27     if(mult(a,b,no[0])>0)
    28         return 1;
    29     else if(mult(a,b,no[0])==0&&dis(a,no[0])<dis(b,no[0]))
    30         return 1;
    31     return 0;
    32 }
    33 
    34 void work()
    35 {
    36     k=0;
    37     for(i=1; i<n; i++)
    38     {
    39         if(no[k].y>no[i].y || ((no[k].y == no[i].y) && no[k].x > no[i].x))
    40             k = i;
    41     }
    42     Node tmp;
    43     tmp = no[0];
    44     no[0] = no[k];
    45     no[k] = tmp;
    46     sort(no+1,no+n,cmp);
    47     top = 2;
    48     stack[0] = no[0];
    49     stack[1] = no[1];
    50     stack[2] = no[2];
    51     for(i=3; i<n; i++)
    52     {
    53         while(top>1 && mult(no[i],stack[top],stack[top-1])>=0)
    54             top--;
    55         stack[++top] = no[i];
    56     }
    57 }
    58 
    59 int main()
    60 {
    61     while(~scanf("%lld",&n))
    62     {
    63         for(i=0; i<n; i++)
    64             scanf("%lld%lld",&no[i].x,&no[i].y);
    65         work();
    66         ans=INF;
    67         for(i=0; i<=top; i++)
    68         {
    69             for(j=i+1; j<=top; j++)
    70             {
    71                 if(ans<dis(stack[i],stack[j]))
    72                     ans=dis(stack[i],stack[j]);
    73             }
    74         }
    75         printf("%lld
    ",ans);
    76     }
    77     return 0;
    78 }


  • 相关阅读:
    主流浏览器默认限制的非安全端口号有哪些
    coco2dx实现翻拍效果
    iOS和android游戏纹理优化和内存优化(cocos2d-x)(转载)
    cocos2d-x如何解决图片显示模糊问题
    cocos2dx混合模式应用———制作新手引导高亮区域
    visual studio的项目属性表
    如何提高cocos2d-x-spine骨骼动画加载速度
    如何调试lua脚本
    把.pvr.ccz文件转换成png
    coco2dx加载网络图片并保存
  • 原文地址:https://www.cnblogs.com/zpfbuaa/p/5074741.html
Copyright © 2020-2023  润新知