poj2187 Beauty Contest(旋转卡壳)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 31214 | Accepted: 9681 |
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
Hint
求平面的最远点对。
由于点的范围在-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(旋转卡壳)的更多相关文章
- poj 2187:Beauty Contest(旋转卡壳)
Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 32708 Accepted: 10156 Description Bes ...
- poj 2187 Beauty Contest , 旋转卡壳求凸包的直径的平方
旋转卡壳求凸包的直径的平方 板子题 #include<cstdio> #include<vector> #include<cmath> #include<al ...
- poj 2187 Beauty Contest——旋转卡壳
题目:http://poj.org/problem?id=2187 学习材料:https://blog.csdn.net/wang_heng199/article/details/74477738 h ...
- P1452 Beauty Contest 旋转卡壳
\(\color{#0066ff}{题目描述}\) 贝茜在牛的选美比赛中赢得了冠军"牛世界小姐".因此,贝西会参观N(2 < = N < = 50000)个农场来传播善 ...
- poj 2187 Beauty Contest —— 旋转卡壳
题目:http://poj.org/problem?id=2187 学习资料:https://blog.csdn.net/wang_heng199/article/details/74477738 h ...
- POJ-2187 Beauty Contest,旋转卡壳求解平面最远点对!
凸包(旋转卡壳) 大概理解了凸包A了两道模板题之后在去吃饭的路上想了想什么叫旋转卡壳呢?回来无聊就搜了一下,结果发现其范围真广. 凸包: 凸包就是给定平面图上的一些点集(二维图包),然后求点集组成的 ...
- poj2187 Beauty Contest (凸包 + 旋转卡壳)
Beauty Contest Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 38349 Accepted: 11851 ...
- POJ2187 Beauty Contest (旋转卡壳算法 求直径)
POJ2187 旋转卡壳算法如图 证明:对于直径AB 必然有某一时刻 A和B同时被卡住 所以旋转卡壳卡住的点集中必然存在直径 而卡壳过程显然是O(n)的 故可在O(n)时间内求出直径 凸包具有良好的性 ...
- [USACO2003][poj2187]Beauty Contest(凸包+旋转卡壳)
http://poj.org/problem?id=2187 题意:老题了,求平面内最远点对(让本渣默默想到了悲剧的AHOI2012……) 分析: nlogn的凸包+旋转卡壳 附:http://www ...
随机推荐
- Application.Count.ToString()和Application["count"].ToString()的区别
当属性名中包括特殊字符如 “.”或“-”就不能使用“.”操作符了.操作符只能使用[ ]操作符 为了统计网站的在线人数,我们可以在Global.asa文件中包含如下代码: <SCRIPT LANG ...
- Codeforces739E Gosha is hunting
题意:现在有n个精灵,两种精灵球各m1和m2个,每个精灵单独使用第一种精灵球有pi的概率被捕获,单独使用第二种精灵球有ui的概率被捕获,同时使用有1-(1-pi)*(1-ui)的概率被捕获.一种精灵球 ...
- 無心插柳的Linux學習者代言人——蔡德明
誰是「蔡德明」恐怕沒有多少人知道,不過提到「鳥哥」這個稱號,在臺灣的Linux社群幾乎是無人不知無人不曉,蔡德明正是鳥哥的本名.鳥哥究竟多有名? 如果你是有意學習Linux的初學者,卻不知如何下手,1 ...
- 转:Gulp的目标是取代Grunt
原文来自于:http://www.infoq.com/cn/news/2014/02/gulp Fractal公司积极参与了数个流行Node.js模块的开发,它最近发布了一个新的构建系统gulp,希望 ...
- ASP.NET Web.Config 读资料 (学习笔记)
refer : http://www.cnblogs.com/fish-li/archive/2011/12/18/2292037.html 上面这篇写很好了. 在做项目时,我们经常会遇到一些资料,我 ...
- Qt编程之QString 处理换行
由于之间写过的一篇文章,Unix,windows,Mac里面的换行符不一样,导致处理也不一样,我现在要用QString以行分割(读取的文本文件的里面有换行符).所以要通吃这三种换行符 http://w ...
- BZOJ1119: [POI2009]SLO
1119: [POI2009]SLO Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 379 Solved: 181[Submit][Status] ...
- mongodb sort limit和skip用法
> db.mediaCollection.find().skip().toArray() [ { "_id" : ObjectId("5353463193efef0 ...
- 我学hash_map(1)
本文来源:http://blog.chinaunix.net/uid-26548237-id-3800125.html map是什么? map是键值对(key-value),复杂度是O(n).但是查 ...
- javascript算法挑战
1.翻转字符串算法挑战: 先把字符串转化成数组,再借助数组的reverse方法翻转数组顺序,最后把数组转化成字符串. 你的结果必须得是一个字符串 function reverseString(str) ...