Beauty Contest(graham求凸包算法)
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 25256 | Accepted: 7756 |
Description
Even though Bessie travels directly in a straight line between pairs of farms, the distance between some farms can be quite large, so she wants to bring a suitcase full of hay with her so she has enough food to eat on each leg of her journey. Since Bessie refills her suitcase at every farm she visits, she wants to determine the maximum possible distance she might need to travel so she knows the size of suitcase she must bring.Help Bessie by computing the maximum distance among all pairs of farms.
Input
* Lines 2..N+1: Two space-separated integers x and y specifying coordinate of each farm
Output
Sample Input
4
0 0
0 1
1 1
1 0
Sample Output
2 题意:给n个点的坐标,计算这些点两两距离最大的那个距离; 思路:如果直接枚举,肯定超。所以可以先形成凸包,距离最大的那两个端点一定是凸包中的点。所以形成凸包后再枚举就可以了。
这里用了graham算法,
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int maxn = ;
int top,stack[maxn];
int n;
struct Point
{
double x;
double y;
} point[maxn]; double cross(const Point &a, const Point &b, const Point &c)//三个点的叉积,结果大于0说明bc的极角大于ac的极角,等于0说明共线;
{
return (a.x-c.x)*(b.y-c.y) - (a.y-c.y)*(b.x-c.x);
} double dis(const Point &a, const Point &b)
{
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
} int cmp(const Point &a, const Point &b)//对点排序找出最左最下的那个点作为point[0];
{
if(a.y == b.y)
return a.x < b.x;
return a.y < b.y;
} void Graham()
{
sort(point,point+n,cmp);
for(int i = ; i <= ; i++)
stack[i] = i;
top = ;
for(int i = ; i < n; i++)
{
while(top && cross(point[i],point[stack[top]],point[stack[top-]]) >= )
top--;
stack[++top] = i;
}
int count = top;
stack[++top] = n-;
for(int i = n-; i >= ; i--)
{
while(top != count && cross(point[i],point[stack[top]],point[stack[top-]])>=)
top--;
stack[++top] = i;
}
} int main()
{
while(~scanf("%d",&n))
{
for(int i = ; i < n; i++)
scanf("%lf %lf",&point[i].x,&point[i].y); Graham(); double ans = ,distance;
for(int i = ; i < top; i++)
{
for(int j = ; j < i; j++)
{
distance = dis(point[stack[i]],point[stack[j]]);
if(ans < distance)
ans = distance;
}
}
printf("%.0lf\n",ans);
}
return ;
}
这是经典的计算几何学问题,判断向量p1=(x1,y1)到p2=(x2,y2)是否做左转,只需要判断x1*y2-x2*y1的正负,如果结果为正,则从p1到p2做左转。也就是向量的叉积。
Graham算法是这样的
1.将各点排序(),为保证形成圈,把P0在次放在点表的尾部;
2.准备堆栈:建立堆栈S,栈指针设为t,将0、1、2三个点压入堆栈S;
3.对于下一个点i
只要S[t-1]、S[t]、i不做左转
就反复退栈;
将i压入堆栈S
4.堆栈中的点即为所求凸包;
Beauty Contest(graham求凸包算法)的更多相关文章
- POJ 2187 Beauty Contest (求最远点对,凸包+旋转卡壳)
Beauty Contest Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 24283 Accepted: 7420 D ...
- Graham Scan凸包算法
获得凸包的算法可以算是计算几何中最基础的算法之一了.寻找凸包的算法有很多种,Graham Scan算法是一种十分简单高效的二维凸包算法,能够在O(nlogn)的时间内找到凸包. 首先介绍一下二维向量的 ...
- poj 2187 Beauty Contest(二维凸包旋转卡壳)
D - Beauty Contest Time Limit:3000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u ...
- POJ 1113 Wall(Graham求凸包周长)
题目链接 题意 : 求凸包周长+一个完整的圆周长. 因为走一圈,经过拐点时,所形成的扇形的内角和是360度,故一个完整的圆. 思路 : 求出凸包来,然后加上圆的周长 #include <stdi ...
- HDU 1392 Surround the Trees (Graham求凸包周长)
题目链接 题意 : 让你找出最小的凸包周长 . 思路 : 用Graham求出凸包,然后对每条边求长即可. Graham详解 #include <stdio.h> #include < ...
- POJ2187 Beauty Contest (旋转卡壳算法 求直径)
POJ2187 旋转卡壳算法如图 证明:对于直径AB 必然有某一时刻 A和B同时被卡住 所以旋转卡壳卡住的点集中必然存在直径 而卡壳过程显然是O(n)的 故可在O(n)时间内求出直径 凸包具有良好的性 ...
- Graham求凸包模板
struct P { double x, y; P(, ):x(x), y(y) {} double add(double a, double b){ ; return a+b; } P operat ...
- (模板)graham扫描法、andrew算法求凸包
凸包算法讲解:Click Here 题目链接:https://vjudge.net/problem/POJ-1113 题意:简化下题意即求凸包的周长+2×PI×r. 思路:用graham求凸包,模板是 ...
- nyoj-78-圈水池(Graham算法求凸包)
题目链接 /* Name:nyoj-78-圈水池 Copyright: Author: Date: 2018/4/27 9:52:48 Description: Graham求凸包 zyj大佬的模板, ...
随机推荐
- J2EE 读取文件路径
在J2ee中实现java类读取webcontent/web-inf/config.xml的实现代码 ,其中../config.xml相对于classes的路径 java.net.URL url = t ...
- 转换字符串格式,可用于sql in
/// <summary> /// 转换字符串格式,可用于sql in /// </summary> /// <param name="lst"> ...
- 关于mvc 分页的 这两个结合着用
http://www.cnblogs.com/JackFeng/archive/2010/01/25/JackFeng.html http://www.webdiyer.com/mvcpager/de ...
- log4Net配置详解
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSe ...
- c#中使用数据读取器读取查询结果
今天有时间了. 在看<c#数据库入门经典> ,总结数据读取器查询结果. 针对单个结果集使用读取器,有3中方法: String connString =..; String sql =@&q ...
- iOS-NSSDate的使用
取当前时间的秒数 NSTimeInterval time = [[NSDate date] timeIntervalSince1970];long long int date = (long long ...
- 【POJ1568】【极大极小搜索+alpha-beta剪枝】Find the Winning Move
Description 4x4 tic-tac-toe is played on a board with four rows (numbered 0 to 3 from top to bottom) ...
- Android 学习手札(二) 活动(Activity)组件
1.建立和配置Activity 建立Android工程时已经自动生成了一个默认的Activity,同时也生成了很多与Activity相关的文件,例如,res目录中的XML及图像文件.AndroidMa ...
- SQL服务器名称的更改
SQL服务器名称的更改 1.使用select @@ServerName可以看到当前数据库的服务器名称 2.从Sys.SysServers表中可以看到当前的所有服务器名称 3.使用 sp_drops ...
- JDK和JRE的区别?
很多朋友可能跟我一样,已经使用JAVA开发很久了,可是对JDK,JRE,JVM这三者的联系与区别,一直都是模模糊糊的. 今天特写此文,来整理下三者的关系. JDK : Java Development ...