标签:几何
题目: 题目链接
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