标签:几何
题目: 题目链接

8 0 0 1 0 0 1 1 1 0 2 1 2 0 3 1 3 8 0 0 2 0 0 2 2 2 1 2 3 2 1 3 3 3 0
2 imp
题意:给你n个点,取这n个顶点的某些顶点作为矩形的顶点,问你存不存在两个矩形的面积之和最大。限制条件:这两个举行不能有接触和重叠,但是可以包含在内。
不存在输出"imp"
题解:由于n只有4到30这么大,所以直接暴力求解就可以了。
一、首先我们要判断存不存在矩形,如何判断?
这里有个小技巧,通过确定两个点的对角线来判断能不能构成矩形。
如图:
我们先判断A,B这两点所连的直线是不是水平或者竖直,如果是就跳过。如果是则判断C,D这两个点是不是都存在。如果存在则能构成矩形,如果不能,就不能构成。
然后我们在确定第二个矩形。
二、第二个矩形的确定。
第二个矩形(假设是EFGH)的确定首先要排除点A,B,C,D这四个点,并且EFGH这四个点不能有任何一个在ABCD内(包括边与定点)。(如题图)
但是这里有一种特殊情况。如图:
我们确定了ABCD,但是EFGH包含了ABCD,所以我们要反过来判断ABCD是不是在EFGH内。如果在就取EFGH的面积,如果不在就取ABCD+AEFHG的面积。完毕。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<vector>
#include<bitset>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<cstdlib>
#include<cmath>
#define PI 2*asin(1.0)
#define LL __int64
const int MOD = 1e9 + 7;
const int N = 2e2 + 15;
const int INF = (1 << 30) - 1;
const int letter = 130;
using namespace std;
int n;
int x[N], y[N];
int vis[N][N];
int dis[N][N];
int check(int ax, int ay, int bx, int by, int cx, int cy, int dx, int dy) {
///边界的处理
int maxx = max(ax, bx);
int minx = min(ax, bx);
int maxy = max(ay, by);
int miny = min(ay, by);
///处理好的四个点
int dir[4][2] = {{cx, cy}, {cx, dy}, {dx, cy}, {dx, dy}};
int sum = 0;
int fg = 0;
for(int i = 0; i < 4; i++) {
int xx = dir[i][0];
int yy = dir[i][1];
if(minx <= xx && xx <= maxx && miny <= yy && yy <= maxy) { ///在第一个矩形内
sum++;
///挨着的
if((xx == minx && miny <= yy && yy <= maxy) || (xx == maxx && miny <= yy && yy <= maxy) || (yy == miny && minx <= xx && xx <= maxx) || (yy == maxy && minx <= xx && xx <= maxx)) {
fg = 1;
break;
}
}
}
if(fg == 1) return -1;
if(sum == 4) {
return (maxx - minx) * (maxy - miny);
} ///在矩形里面
else if(sum == 1 || sum == 2 || sum == 3) return -1; ///相交于矩形
else {
///第一个是小的 ,第二个把第一个包含在内
int vir[4][2] = {{minx, miny}, {minx, maxy}, {maxx, miny}, {maxx, maxy}};
int flag = 0;
int fg = 0;
///以第二个矩形为边界
int maxxx = max(cx, dx);
int minxx = min(cx, dx);
int maxyy = max(cy, dy);
int minyy = min(cy, dy);
for(int i = 0; i < 4; i++) {
int xx = vir[i][0];
int yy = vir[i][1];
if(minxx <= xx && xx <= maxxx && minyy <= yy && yy <= maxyy) { ///在第二个矩形内
flag++;
if((xx == minxx && minyy <= yy && yy <= maxyy) || (xx == maxxx && minyy <= yy && yy <= maxyy) ||(yy == minyy && minxx <= xx && xx <= maxxx)||( yy == maxyy && minxx <= xx && xx <= maxxx)) {
fg = 1;
break;
}
}
}
if(fg == 1) return -1;
if(flag != 4) return (maxx - minx) * (maxy - miny) + abs((cx - dx) * (cy - dy));
else return abs((cx - dx) * (cy - dy));
}
}
int main() {
while(scanf("%d", &n) && n) {
int max1 = -1;
memset(vis, 0, sizeof(vis));///地图中存在的点
memset(dis, 0, sizeof(dis));
for(int i = 0; i < n; i++) {
int a, b;
scanf("%d%d", &a, &b);
x[i] = a, y[i] = b;
vis[a][b] = 1;
}
for(int i = 0; i < n; i++)
for(int j = i + 1; j < n; j++) {
if(x[i] != x[j] && y[i] != y[j]) { ///不在同一条直线上
if(vis[x[i]][y[j]] && vis[x[j]][y[i]]) { ///从对角线上找起
for(int k = 0; k < n; k++)
for(int v = k + 1; v < n; v++) {
///判断这四个点是否符合条件
if(x[k] != x[v] && y[k] != y[v]) {
///找到第二个三角形
if(vis[x[k]][y[v]] && vis[x[v]][y[k]]) {
///判断第二个三角形和第一个三角形的关系
max1 = max(max1, check(x[i], y[i], x[j], y[j], x[k], y[k], x[v], y[v]));
}
}
}
}
}
}
if(max1 == -1) printf("imp\n");
else printf("%d\n", max1);
}
return 0;
}HDU5128 The E-pang Palace(2014年广州赛区)
标签:几何
原文地址:http://blog.csdn.net/u014325920/article/details/43193333