POJ 2187 Beauty Contest 凸包的应用

本文讨论了使用凸包解决线段长度问题的方法,包括如何通过凸包找到最长线段并计算其平方长度。文章详细介绍了算法实现步骤及关键代码片段。

//POJ 2187 Beauty Contest 凸包的应用
//题意:给你一连串的点,要你求由这些点连成的线段的中最长的。。
//很明显想到凸包了,,因为最长的点肯定是在凸包上的。。
//好像直接暴搜也可以过。。没试过。。
//注意:须先将n赋值,点数需大于二,求凸包的点的下标放在sta[]中,而不是凸包的点放在point[]中
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstdio>
#include <cmath>
#define pi acos(-1.0)
using namespace std;

typedef double pointper;//点坐标的类型

#define POINTNUM 50005//最多点的个数
#define PREX 1e-11  //当点坐标为实数型的时候用

struct node
{
 pointper x,y;
}Point[10001];

class Polygon
{
public:
 int sta[POINTNUM];//在凸包上点的坐标
 node point[POINTNUM];
 bool flag[POINTNUM];
 int top,n,stab;//n为读入的点的个数,top-1为凸包上点的个数,(0~~top-2)是凸包上点的坐标,top-1和0存的都是第一个点;
 pointper x1,y1,x2,y2;
// polygon()加这个进去就CE了。。所以去掉它。。
// {
//  top=0;
//  n=0;
// }
 static bool cmp(const node &A,const node &B)
 {
  return A.x<B.x||A.x==B.x&&A.y<B.y;//先根据X排序,然后根据Y排序
 }
 bool X(int x1,int y1,int x2,int y2,bool f)//f为true表示求的包括边上的点
 {
  if(f)
   return x1*y2-x2*y1>=0;
  return x1*y2-x2*y1>0;
 }
 bool X(double x1,double y1,double x2,double y2,bool f)//f为true表示求的包括边上的点
 {
  if(f)
   return x1*y2-x2*y1>=0.0||fabs(x1*y2-x2*y1)<PREX;
  return x1*y2-x2*y1>0.0;
 }
 double dis(node a,node b)
 {
        return sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
 }
 void pointselect(bool f);//求凸包上的点,f为true表示求的包括边上的点;
 void getpoint(int i,bool f);
 void XY(int i);//辅助X()求叉乘
 double length();//求凸包的周长
 double area();//求凸包的面积;
 bool IsInPoly(int x,int y,bool f);
 bool IsInPoly(double x,double y,bool f);
};

Polygon Tubao;

void Polygon::XY(int i)
{
 x1=point[i].x-point[sta[top-2]].x;
 y1=point[i].y-point[sta[top-2]].y;
 x2=point[sta[top-1]].x-point[sta[top-2]].x;
 y2=point[sta[top-1]].y-point[sta[top-2]].y;
}

void Polygon::getpoint(int i,bool f)
{
 XY(i);
 if(top==stab||X(x1,y1,x2,y2,f))
 {
  sta[top++]=i;
  flag[i]=false;
 }
 else
 {
  top--;
  flag[sta[top]]=true;
  XY(i);
  while(top>stab&&!X(x1,y1,x2,y2,f))
  {
   top--;
   flag[sta[top]]=true;
   XY(i);
  }
  sta[top++]=i;
  flag[i]=false;
 }
}
void Polygon::pointselect(bool f)
{
 int i;
 memset(flag,true,n+1);
 sort(point,point+n,cmp);
 sta[0]=0;
 sta[1]=1;
 top=2;
 flag[1]=false;
 stab=1;
 for(i=2;i<n;i++)
  getpoint(i,f);
 stab=top;
 for(i=n-2;i>=0;i--)
  if(flag[i])
   getpoint(i,f);
}

double Polygon::length()
{
 double s=0.0;
 int i;
 for(i=1;i<top;i++)
  s+=sqrt(1.0*(point[sta[i]].x-point[sta[i-1]].x)*(point[sta[i]].x-point[sta[i-1]].x)+(point[sta[i]].y-point[sta[i-1]].y)*(point[sta[i]].y-point[sta[i-1]].y));
  return s;
}
double Polygon::area()
{
 double s=0.0;
 int i;
 for(i=1;i<top;i++)
  s+=point[sta[i-1]].x*point[sta[i]].y-point[sta[i]].x*point[sta[i-1]].y;
 return fabs(s/2);
}

bool Polygon::IsInPoly(int x,int y,bool f)//int型
{
 int i;
 for(i=1;i<top;i++)
  if(!X(x-point[sta[i-1]].x,y-point[sta[i-1]].y,(double)point[sta[i]].x-point[sta[i-1]].x,(double)point[sta[i]].y-point[sta[i-1]].y,f))
   return false;
  return true;
}

bool Polygon::IsInPoly(double x,double y,bool f)//double型
{
 int i;
 for(i=1;i<top;i++)
  if(!X(x-point[sta[i-1]].x,y-point[sta[i-1]].y,point[sta[i]].x-point[sta[i-1]].x,point[sta[i]].y-point[sta[i-1]].y,f))
   return false;
  return true;
}

int main()//
{
 int i,j;
 while(scanf("%d",&Tubao.n)!=EOF&&Tubao.n)
 {
  for(i=0;i<Tubao.n;i++)
  {
   cin>>Tubao.point[i].x>>Tubao.point[i].y;
  }
  Tubao.pointselect(1);
  double a;
  double  max=0;
 //  for(i=1;i<Tubao.top;i++)//Tubao.top存的就是凸包里面的个数。。
 // cout<<Tubao.point[Tubao.sta[i]].x<<" "<<Tubao.point[Tubao.sta[i]].y<<endl;
     for(i=1;i<Tubao.top;i++) 
   for(j=i+1;j<Tubao.top;j++)
    {
     a=Tubao.dis(Tubao.point[Tubao.sta[i]],Tubao.point[Tubao.sta[j]]);
     if(a>max)
      max=a;
    }
    printf("%.0lf\n",max*max);//看了半天才知道是求最长的平方。。
 }
 return 0;
}

转载于:https://www.cnblogs.com/Mu-Tou/archive/2011/08/10/2134232.html

AI-PPT 一键生成 PPT:用户输入主题关键词,AI-PPT 可快速生成完整 PPT,涵盖标题、正文、段落结构等,还支持对话式生成,用户可在 AI 交互窗口边查看边修改。 文档导入转 PPT:支持导入 Word、Excel、PDF 等多种格式文档,自动解析文档结构,将其转换为结构清晰、排版规范的 PPT,有保持原文和智能优化两种模式。 AI-PPT 对话 实时问答:用户上传 PPT 或 PPTX 文件后,可针对演示内容进行提问,AI 实时提供解答,帮助用户快速理解内容。 多角度内容分析:对 PPT 内容进行多角度分析,提供全面视野,帮助用户更好地把握内容结构和重点。 多语言对话支持:支持多语言对话,打破语言障碍,方便不同语言背景的用户使用。 AI - 绘图 文生图:用户输入文字描述,即可生成符合语义的不同风格图像,如油画、水彩、中国画等,支持中英文双语输入。 图生图:用户上传图片并输入描述,AI - 绘图能够根据参考图和描述生成新的风格化图像,适用于需要特定风格或元素的创作需求。 图像编辑:提供如 AI 超清、AI 扩图、AI 无痕消除等功能,用户可以上传图片进行细节修改和优化,提升图片质量。 AI - 文稿 文案生成:能够根据用户需求生成多种类型的文章,如市场营销文案、技术文档、内部沟通内容等,提升文案质量和创作效率。 文章润色:对已有文章进行改善和优化,包括语言表达、逻辑连贯性、内容流畅度等方面,使文章更符合用户期望和风格。 文章续写:AI 技术理解文本语境,为用户提供新的想法、补充资料或更深层次的见解,帮助用户丰富文档内容。 AI - 医生 智能健康咨询:包括症状自查,用户输入不适症状,AI 结合病史等信息提供疾病可能性分析与初步建议;用药指导,支持查询药品适应症、禁忌症等,并预警潜在冲突;中医辨证,提供体质辨识与调理建议。 医学报告解读:用户上传体检报告
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值