转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud

Beauty Contest
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 31214   Accepted: 9681

Description

Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, earning the title 'Miss Cow World'. As a result, Bessie will make a tour of N (2 <= N <= 50,000) farms around the world in order to spread goodwill between farmers and their cows. For simplicity, the world will be represented as a two-dimensional plane, where each farm is located at a pair of integer coordinates (x,y), each having a value in the range -10,000 ... 10,000. No two farms share the same pair of coordinates.

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

* Line 1: A single integer, N

* Lines 2..N+1: Two space-separated integers x and y specifying coordinate of each farm

Output

* Line 1: A single integer that is the squared distance between the pair of farms that are farthest apart from each other. 

Sample Input

4
0 0
0 1
1 1
1 0

Sample Output

2

Hint

Farm 1 (0, 0) and farm 3 (1, 1) have the longest distance (square root of 2) 

求平面的最远点对。

由于点的范围在-10000到10000之间,所以取完凸包后,凸包上的点的数目并不会很多,不会超过根号M个,所以可以求完凸包之后直接暴力枚举凸包上的点来做。

 /**
* code generated by JHelper
* More info: https://github.com/AlexeyDmitriev/JHelper
* @author xyiyy @https://github.com/xyiyy
*/ #include <iostream>
#include <fstream> //#####################
//Author:fraud
//Blog: http://www.cnblogs.com/fraud/
//#####################
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype> using namespace std;
#define rep(X, N) for(int X=0;X<N;X++) const double EPS = 1e-; double add(double a, double b) {
if (abs(a + b) < EPS * (abs(a) + abs(b)))return ;
return a + b;
} struct P {
double x, y; P() { } P(double x, double y) : x(x), y(y) { } P operator+(P p) {
return P(add(x, p.x), add(y, p.y));
} P operator-(P p) {
return P(add(x, -p.x), add(y, -p.y));
} double dot(P p) {
return add(x * p.x, y * p.y);
} double det(P p) {
return add(x * p.y, -y * p.x);
}
}; double dist(P p, P q) {
return (p - q).dot(p - q);
} bool cmp_x(const P &p, const P &q) {
if (p.x != q.x)return p.x < q.x;
return p.y < q.y;
} vector<P> convex_hull(P *ps, int n) {
sort(ps, ps + n, cmp_x);
int k = ;
vector<P> qs(n * );
for (int i = ; i < n; qs[k++] = ps[i++]) {
while (k > && (qs[k - ] - qs[k - ]).det(ps[i] - qs[k - ]) < EPS)k--;
}
for (int i = n - , t = k; i >= ; qs[k++] = ps[i--]) {
while (k > t && (qs[k - ] - qs[k - ]).det(ps[i] - qs[k - ]) < EPS)k--;
}
qs.resize(k - );
return qs;
} const int MAXN = ; class poj2187 {
public:
void solve() {
int n;
scanf("%d",&n);//in >> n;
P *ps = new P[MAXN];
rep(i, n) {
scanf("%lf%lf",&ps[i].x,&ps[i].y);//in >> ps[i].x >> ps[i].y;
}
vector<P> qs = convex_hull(ps, n);
double res = ;
rep(i, qs.size()) {
rep(j, i) {
res = max(res, dist(qs[i], qs[j]));
}
}
printf("%.0f\n",res);
//out << fixed << setprecision(0) << res << endl;
}
}; int main() {
//std::ios::sync_with_stdio(false);
//std::cin.tie(0);
poj2187 solver;
//std::istream &in(std::cin);
// std::ostream &out(std::cout);
solver.solve();
return ;
}

代码君

对于凸包上最远的两个点,其实可以使用旋转卡壳来做,其实旋转卡壳的思想是比较容易理解的,首先找到对踵点对,

不明白的可以先看一下以下链接

https://en.wikipedia.org/wiki/Rotating_calipers

然后在考虑转移的情况,在凸包上,对于一个点和其他所有点的距离,绕一圈,正好构成一个单峰函数,那么,对踵点对就一定是在变小的那个地方,所以这样想通后只要找出所有的对踵点对间距离的最大值,这样原来需要在凸包上枚举所有点的O(n^2)的方法就可以通过旋转卡壳改进成O(n)了,外加上前面求凸包O(nlogn)的复杂度,这道题就可以轻松切掉了。

下面附上C++版和Java版的代码

C++:

 /**
* code generated by JHelper
* More info: https://github.com/AlexeyDmitriev/JHelper
* @author xyiyy @https://github.com/xyiyy
*/ #include <iostream>
#include <fstream> //#####################
//Author:fraud
//Blog: http://www.cnblogs.com/fraud/
//#####################
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype> using namespace std;
#define rep(X, N) for(int X=0;X<N;X++) //
// Created by xyiyy on 2015/8/10.
// #ifndef JHELPER_EXAMPLE_PROJECT_P_HPP
#define JHELPER_EXAMPLE_PROJECT_P_HPP const double EPS = 1e-; double add(double a, double b) {
if (fabs(a + b) < EPS * (fabs(a) + fabs(b)))return ;
return a + b;
} class P {
public:
double x, y;
P() {}
P(double x, double y):x(x),y(y){} P operator+(const P &p) {
return P(add(x, p.x), add(y, p.y));
} P operator-(const P &p) {
return P(add(x, -p.x), add(y, -p.y));
} P operator*(const double &d) {
return P(x * d, y * d);
} P operator/(const double &d) {
return P(x / d, y / d);
} double dot(P p) {
return add(x * p.x, y * p.y);
} double det(P p) {
return add(x * p.y, -y * p.x);
} double abs() {
return sqrt(abs2());
} double abs2() {
return dot(*this);
} }; //直线和直线的交点
/*P isLL(P p1,P p2,P q1,P q2){
double d = (q2 - q1).det(p2 - p1);
if(sig(d)==0)return NULL;
return intersection(p1,p2,q1,q2);
}*/ //四点共圆判定
/*bool onC(P p1,P p2,P p3,P p4){
P c = CCenter(p1,p2,p3);
if(c == NULL) return false;
return add((c - p1).abs2(), -(c - p4).abs2()) == 0;
}*/ //三点共圆的圆心
/*P CCenter(P p1,P p2,P p3){
//if(disLP(p1, p2, p3) < EPS)return NULL;//三点共线
P q1 = (p1 + p2) * 0.5;
P q2 = q1 + ((p1 - p2).rot90());
P s1 = (p3 + p2) * 0.5;
P s2 = s1 + ((p3 - p2).rot90());
return isLL(q1,q2,s1,s2);
}*/
bool cmp_x(const P &p, const P &q) {
if (p.x != q.x) return p.x < q.x;
return p.y < q.y;
} vector<P> qs; void convex_hull(P *ps, int n) {
sort(ps, ps + n, cmp_x);
int k = ;
qs.resize( * n);
for (int i = ; i < n; qs[k++] = ps[i++]) {
while (k > && (qs[k - ] - qs[k - ]).det(ps[i] - qs[k - ]) < EPS)k--;
}
for (int i = n - , t = k; i >= ; qs[k++] = ps[i--]) {
while (k > t && (qs[k - ] - qs[k - ]).det(ps[i] - qs[k - ]) < EPS)k--;
}
qs.resize(k - );
} //求凸包的直径
double convexDiameter() {
int qsz = qs.size();
if (qsz == )return ;
if (qsz == ) {
return (qs[] - qs[]).abs();
}
int i = , j = ;
rep(k, qsz) {
if (!cmp_x(qs[i], qs[k]))i = k;
if (cmp_x(qs[j], qs[k])) j = k;
}
double res = ;
int si = i, sj = j;
while (i != sj || j != si) {
res = max(res, (qs[i] - qs[j]).abs());
if ((qs[(i + ) % qsz] - qs[i]).det(qs[(j + ) % qsz] - qs[j]) < ) i = (i + ) % qsz;
else j = (j + ) % qsz;
}
return res;
} #endif //JHELPER_EXAMPLE_PROJECT_P_HPP const int MAXN = ;
P p[MAXN]; class poj2187_Rotating_calipers {
public:
void solve() {
int n;
scanf("%d",&n);//in >> n;
rep(i, n) {
scanf("%lf%lf",&p[i].x,&p[i].y);//in >> p[i].x >> p[i].y;
}
convex_hull(p, n);
double ans = convexDiameter();
printf("%.0f\n",ans*ans);//out << ans * ans << endl;
}
}; int main() {
//std::ios::sync_with_stdio(false);
//std::cin.tie(0);
poj2187_Rotating_calipers solver;
//std::istream &in(std::cin);
//std::ostream &out(std::cout);
solver.solve();
return ;
}

代码君

Java:

 import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStream; /**
* Built using CHelper plug-in
* Actual solution is at the top
*
* @author xyiyy @https://github.com/xyiyy @http://www.cnblogs.com/fraud/
*/
public class Main {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
Scanner in = new Scanner(inputStream);
PrintWriter out = new PrintWriter(outputStream);
TaskC solver = new TaskC();
solver.solve(, in, out);
out.close();
} static class TaskC {
Scanner in;
PrintWriter out; public void solve(int testNumber, Scanner in, PrintWriter out) {
this.in = in;
this.out = out;
run();
} void run() {
int n;
n = in.nextInt();
P[] p = new P[n];
for (int i = ; i < n; i++) p[i] = new P(in.nextInt(), in.nextInt());
double ans = P.convexDiameter(P.convexHull(p));
out.printf("%.0f%n", ans * ans);
} } static class P implements Comparable<P> {
public static final double EPS = 1e-;
public final double x;
public final double y; public static double add(double a, double b) {
if (Math.abs(a + b) < EPS * (Math.abs(a) + Math.abs(b))) return ;
return a + b;
} public P(double x, double y) {
this.x = x;
this.y = y;
} public P sub(P p) {
return new P(add(x, -p.x), add(y, -p.y));
} public double det(P p) {
return add(x * p.y, -y * p.x);
} public double dot(P p) {
return add(x * p.x, y * p.y);
} public double abs() {
return Math.sqrt(abs2());
} public double abs2() {
return dot(this);
} public String toString() {
return "(" + x + ", " + y + ")";
} public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
return compareTo((P) obj) == ;
} public int compareTo(P p) {
int b = sig(x - p.x);
if (b != ) return b;
return sig(y - p.y);
} public static int sig(double x) {
if (Math.abs(x) < EPS) return ;
return x < ? - : ;
} public static P[] convexHull(P[] ps) {
int n = ps.length, k = ;
if (n <= ) return ps;
Arrays.sort(ps);
P[] qs = new P[n * ];
for (int i = ; i < n; qs[k++] = ps[i++]) {
while (k > && qs[k - ].sub(qs[k - ]).det(ps[i].sub(qs[k - ])) < EPS) k--;
}
for (int i = n - , t = k; i >= ; qs[k++] = ps[i--]) {
while (k > t && qs[k - ].sub(qs[k - ]).det(ps[i].sub(qs[k - ])) < EPS) k--;
}
P[] res = new P[k - ];
System.arraycopy(qs, , res, , k - );
return res;
} public static double convexDiameter(P[] ps) {
int n = ps.length;
int is = , js = ;
for (int i = ; i < n; i++) {
if (ps[i].x > ps[is].x) is = i;
if (ps[i].x < ps[js].x) js = i;
}
double maxD = ps[is].sub(ps[js]).abs();
int i = is, j = js;
do {
if (ps[(i + ) % n].sub(ps[i]).det(ps[(j + ) % n].sub(ps[j])) >= ) {
j = (j + ) % n;
} else {
i = (i + ) % n;
}
maxD = Math.max(maxD, ps[i].sub(ps[j]).abs());
} while (i != is || j != js);
return maxD;
} } static class Scanner {
BufferedReader br;
StringTokenizer st; public Scanner(InputStream in) {
br = new BufferedReader(new InputStreamReader(in));
eat("");
} private void eat(String s) {
st = new StringTokenizer(s);
} public String nextLine() {
try {
return br.readLine();
} catch (IOException e) {
return null;
}
} public boolean hasNext() {
while (!st.hasMoreTokens()) {
String s = nextLine();
if (s == null)
return false;
eat(s);
}
return true;
} public String next() {
hasNext();
return st.nextToken();
} public int nextInt() {
return Integer.parseInt(next());
} }
}

代码君

poj2187 Beauty Contest(旋转卡壳)的更多相关文章

  1. poj 2187:Beauty Contest(旋转卡壳)

    Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 32708   Accepted: 10156 Description Bes ...

  2. poj 2187 Beauty Contest , 旋转卡壳求凸包的直径的平方

    旋转卡壳求凸包的直径的平方 板子题 #include<cstdio> #include<vector> #include<cmath> #include<al ...

  3. poj 2187 Beauty Contest——旋转卡壳

    题目:http://poj.org/problem?id=2187 学习材料:https://blog.csdn.net/wang_heng199/article/details/74477738 h ...

  4. P1452 Beauty Contest 旋转卡壳

    \(\color{#0066ff}{题目描述}\) 贝茜在牛的选美比赛中赢得了冠军"牛世界小姐".因此,贝西会参观N(2 < = N < = 50000)个农场来传播善 ...

  5. poj 2187 Beauty Contest —— 旋转卡壳

    题目:http://poj.org/problem?id=2187 学习资料:https://blog.csdn.net/wang_heng199/article/details/74477738 h ...

  6. POJ-2187 Beauty Contest,旋转卡壳求解平面最远点对!

     凸包(旋转卡壳) 大概理解了凸包A了两道模板题之后在去吃饭的路上想了想什么叫旋转卡壳呢?回来无聊就搜了一下,结果发现其范围真广. 凸包: 凸包就是给定平面图上的一些点集(二维图包),然后求点集组成的 ...

  7. poj2187 Beauty Contest (凸包 + 旋转卡壳)

    Beauty Contest Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 38349   Accepted: 11851 ...

  8. POJ2187 Beauty Contest (旋转卡壳算法 求直径)

    POJ2187 旋转卡壳算法如图 证明:对于直径AB 必然有某一时刻 A和B同时被卡住 所以旋转卡壳卡住的点集中必然存在直径 而卡壳过程显然是O(n)的 故可在O(n)时间内求出直径 凸包具有良好的性 ...

  9. [USACO2003][poj2187]Beauty Contest(凸包+旋转卡壳)

    http://poj.org/problem?id=2187 题意:老题了,求平面内最远点对(让本渣默默想到了悲剧的AHOI2012……) 分析: nlogn的凸包+旋转卡壳 附:http://www ...

随机推荐

  1. Web之CSS开发技巧: CSS @media

    CSS @media 规则非常适合于将 HTML 或 XML 文档定位为目标输出方法.目前,print 媒体的使用非常普遍,与实现单独的 “可打印版本” 相比,print 提供了更加整洁的方式来创建打 ...

  2. Python Socket Programming

    本文介绍使用Python进行Socket网络编程,假设读者已经具备了基本的网络编程知识和Python的基本语法知识,本文中的代码如果没有说明则都是运行在Python 3.4下. Python的sock ...

  3. C++学习笔记1——const

    Const 限定符 1. 等价 //const对象必须初始化//C++中const修饰的变量不能改变//C中const修饰的变量可以通过指针修改 2. ; const int j = i;//变量给常 ...

  4. ubuntu 12.04 安装nginx

    nginx是一个强大的高性能反向代理服务器,其特点是占内存少,并发能力强,在高并发的情况下是apache 的一个不错的代替品,能够支持高达50000个并发连接数的响应,那么这么强大的武器,究竟如何在l ...

  5. 【问题】pod setup 问题

    安装pod setup 的时候,可能会安装失败,可以多试几次,但是如果一直失败,那就是由问题了. 解决办法: 1. 分别执行下面命令卸载cocoapods和xcodeproj,如果你的机器上面有多个版 ...

  6. Go http.HandlerFunc()

    //http.Handler type Handler interface { ServeHTTP(ResponseWriter, *Request) } type HandlerFunc func( ...

  7. c++ 高效文本读写

    上数据结构课,做project,数据老师要求我们多做测试,而文本文件可以有效记录这些东东,这样我想起了文件的读写,下面是渣渣我个人的一些想法,大神们看见有错的,尽管指出(orz~~~囧,木有人看我的呀 ...

  8. Android的理解

    从组件的角度来考虑 Activity------------------Service-----------------Broadcast Receiver---------------------- ...

  9. C# 注销掉事件,解决多播委托链表的问题

    c#的事件是多播委托.当绑定多个事件时,事件会依次触发,清除掉注册的委托链表:方法1  C# Code  12345678910111213141516171819202122232425262728 ...

  10. expect: spawn id exp4 not open

    spawn rsync -avH --delete /home/dwetl/bin dwetl@10.128.8.151:/home/dwetl/bin sending incremental fil ...