POJ 2079 Triangle (平面点最大三角形 凸包+旋转卡壳 推荐)
2016-10-04 10:44
531 查看
[align=center]Triangle[/align]
Description
Given n distinct points on a plane, your task is to find the triangle that have the maximum area, whose vertices are from the given points.
Input
The input consists of several test cases. The first line of each test case contains an integer n, indicating the number of points on the plane. Each of the following n lines contains two integer xi
and yi, indicating the ith points. The last line of the input is an integer −1, indicating the end of input, which should not be processed. You may assume that 1 <= n <= 50000 and −104 <= xi, yi <= 104 for all i = 1 . . . n.
Output
For each test case, print a line containing the maximum area, which contains two digits after the decimal point. You may assume that there is always an answer which is greater than zero.
Sample Input
Sample Output
Source
Shanghai 2004 Preliminary
题目链接:http://poj.org/problem?id=2079
题目大意:平面上给n个点求任意三点能组成的最大三角形面积
题目分析;显然最大三角形的三个顶点都在凸包上(可以通过反证法),求出凸包后枚举两个点,第三个点根据单调性直接逆时针旋转即可,时间复杂度O(n^2),n方可做是因为坐标是整数点且范围到lim的纯净凸包上的点数量在sqrt(lim)附近,画个图就可以看出来,可以让横坐标每次x = x + 1,纵坐标y = y + x + 1,这样算下来,总的点数接近n*(n+1)/2 + n*(n+1)/2 + n = n^2 + 2n,n^2 + 2n < lim
=> n ~ sqrt(lim),所以总点数也就在200多左右,n^2的旋转卡壳很快就能过。网上很多O(n)的代码都是错的,以下数据总有一组通不过(来自poj discuss)
答案:
38.50
15.00
15.00
15.00
n^2,282ms
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int const MAX = 5e4 + 5;
int n;
struct POINT {
int x, y;
}p[MAX], stk[MAX], base;
double getDist(POINT a, POINT b) {
return sqrt(1.0 * (a.x - b.x) * (a.x - b.x) + 1.0 * (a.y - b.y) * (a.y - b.y));
}
double getCross(POINT p0, POINT p1, POINT p2) {
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
bool cmp(POINT p1, POINT p2) {
if (getCross(base, p1, p2) == 0) {
return getDist(base, p1) < getDist(base, p2);
}
if (getCross(base, p1, p2) > 0) {
return true;
}
return false;
}
void getBase() {
scanf("%d %d", &p[0].x, &p[0].y);
base.x = p[0].x;
base.y = p[0].y;
int pos = 0;
for (int i = 1; i < n; i ++) {
scanf("%d %d", &p[i].x, &p[i].y);
if (p[i].y < base.y || (p[i].y == base.y && p[i].x < base.x)) {
base.x = p[i].x;
base.y = p[i].y;
pos = i;
}
}
swap(p[0], p[pos]);
}
int main() {
while (scanf("%d", &n) && n != -1) {
getBase();
sort(p + 1, p + n, cmp);
stk[0] = p[0];
stk[1] = p[1];
int top = 1;
for (int i = 2; i < n; i ++) {
while (top > 0 && getCross(stk[top - 1], stk[top], p[i]) <= 0) {
top --;
}
stk[++ top] = p[i];
}
double ans = 0;
stk[++ top] = stk[0];
for (int i = 0; i < top; i ++) {
int k = 2;
for (int j = i + 1; j <= top; j ++) {
while(getCross(stk[i], stk[j], stk[k]) < getCross(stk[i], stk[j], stk[(k + 1) % top])) {
k = (k + 1) % top;
}
ans = max(ans, 0.5 * getCross(stk[i], stk[j], stk[k]));
}
}
printf("%.2f\n", ans);
}
}
Time Limit: 3000MS | Memory Limit: 30000K | |
Total Submissions: 9424 | Accepted: 2805 |
Given n distinct points on a plane, your task is to find the triangle that have the maximum area, whose vertices are from the given points.
Input
The input consists of several test cases. The first line of each test case contains an integer n, indicating the number of points on the plane. Each of the following n lines contains two integer xi
and yi, indicating the ith points. The last line of the input is an integer −1, indicating the end of input, which should not be processed. You may assume that 1 <= n <= 50000 and −104 <= xi, yi <= 104 for all i = 1 . . . n.
Output
For each test case, print a line containing the maximum area, which contains two digits after the decimal point. You may assume that there is always an answer which is greater than zero.
Sample Input
3 3 4 2 6 2 7 5 2 6 3 9 2 0 8 0 6 5 -1
Sample Output
0.50 27.00
Source
Shanghai 2004 Preliminary
题目链接:http://poj.org/problem?id=2079
题目大意:平面上给n个点求任意三点能组成的最大三角形面积
题目分析;显然最大三角形的三个顶点都在凸包上(可以通过反证法),求出凸包后枚举两个点,第三个点根据单调性直接逆时针旋转即可,时间复杂度O(n^2),n方可做是因为坐标是整数点且范围到lim的纯净凸包上的点数量在sqrt(lim)附近,画个图就可以看出来,可以让横坐标每次x = x + 1,纵坐标y = y + x + 1,这样算下来,总的点数接近n*(n+1)/2 + n*(n+1)/2 + n = n^2 + 2n,n^2 + 2n < lim
=> n ~ sqrt(lim),所以总点数也就在200多左右,n^2的旋转卡壳很快就能过。网上很多O(n)的代码都是错的,以下数据总有一组通不过(来自poj discuss)
6 4 -5 6 -2 5 2 -4 5 -6 2 -5 -2 5 -7 0 -5 1 -1 5 -2 8 -8 4 5 0 7 1 5 5 1 8 2 4 8 5 0 -7 4 -8 8 -2 5 -1 1 -5 -1
答案:
38.50
15.00
15.00
15.00
n^2,282ms
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int const MAX = 5e4 + 5;
int n;
struct POINT {
int x, y;
}p[MAX], stk[MAX], base;
double getDist(POINT a, POINT b) {
return sqrt(1.0 * (a.x - b.x) * (a.x - b.x) + 1.0 * (a.y - b.y) * (a.y - b.y));
}
double getCross(POINT p0, POINT p1, POINT p2) {
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
bool cmp(POINT p1, POINT p2) {
if (getCross(base, p1, p2) == 0) {
return getDist(base, p1) < getDist(base, p2);
}
if (getCross(base, p1, p2) > 0) {
return true;
}
return false;
}
void getBase() {
scanf("%d %d", &p[0].x, &p[0].y);
base.x = p[0].x;
base.y = p[0].y;
int pos = 0;
for (int i = 1; i < n; i ++) {
scanf("%d %d", &p[i].x, &p[i].y);
if (p[i].y < base.y || (p[i].y == base.y && p[i].x < base.x)) {
base.x = p[i].x;
base.y = p[i].y;
pos = i;
}
}
swap(p[0], p[pos]);
}
int main() {
while (scanf("%d", &n) && n != -1) {
getBase();
sort(p + 1, p + n, cmp);
stk[0] = p[0];
stk[1] = p[1];
int top = 1;
for (int i = 2; i < n; i ++) {
while (top > 0 && getCross(stk[top - 1], stk[top], p[i]) <= 0) {
top --;
}
stk[++ top] = p[i];
}
double ans = 0;
stk[++ top] = stk[0];
for (int i = 0; i < top; i ++) {
int k = 2;
for (int j = i + 1; j <= top; j ++) {
while(getCross(stk[i], stk[j], stk[k]) < getCross(stk[i], stk[j], stk[(k + 1) % top])) {
k = (k + 1) % top;
}
ans = max(ans, 0.5 * getCross(stk[i], stk[j], stk[k]));
}
}
printf("%.2f\n", ans);
}
}
相关文章推荐
- POJ 2079 Triangle(凸包+旋转卡壳求最大三角形面积)
- POJ 2079 Triangle(凸包_旋转卡壳之最大三角形面积)
- POJ 2079 Triangle (凸包中的最大三角形&旋转卡壳)
- POJ 2079 Triangle(凸包+旋转卡壳,求最大三角形面积)
- poj 2079 Triangle 凸包+旋转卡壳 求最大三角形面积
- POJ 2079 Triangle(旋转卡壳计算平面点集最大三角形面积)
- POJ 2079 Triangle(凸包+旋转卡壳,求最大三角形面积)
- POJ 2079 求最大三角形面积 (凸包+旋转卡壳)
- hdu 3934&&poj 2079 (凸包+旋转卡壳+求最大三角形面积)
- poj2079 Triangle (旋转卡壳之最大三角形)
- poj 2079(旋转卡壳求解凸包内最大三角形面积)
- poj 2079 Triangle,旋转卡壳求点集的最大三角形
- poj 2079 Triangle,旋转卡壳求点集的最大三角形
- POJ 2079 Triangle(凸包,最大三角形)
- POJ 2079 Triangle 凸包+旋转卡壳
- poj 2079 Triangle (二维凸包旋转卡壳)
- poj 2079 Triangle(凸包+旋转卡壳)
- POJ 2079 Triangle(凸包-旋转卡壳)
- POJ 2187 Beauty Contest (平面最远点对 凸包+旋转卡壳 推荐)
- poj 2079 Triangle 凸包+旋转卡壳