UVa 1331 Minimax Triangulation

来源:互联网 发布:vs源码加密 编辑:程序博客网 时间:2024/05/01 06:14

Triangulation of surfaces has applications in the Finite Element Method of solid mechanics. The objective is to estimate the stress and strain on complex objects by partitioning them into small simple objects which are considered incompressible. It is convenient to approximate a plane surface with a simple polygon, i.e., a piecewise-linear, closed curve in the plane on m distinct vertices, which does not intersect itself. A chord is a line segment between two non-adjacent vertices of the polygon which lies entirely inside the polygon, so in particular, the endpoints of the chord are the only points of the chord that touch the boundary of the polygon. A triangulation of the polygon, is any choice of m -3 chords, such that the polygon is divided into triangles. In a triangulation, no two of the chosen chords intersect each other, except at endpoints, and all of the remaining (unchosen) chords cross at least one of the chosen chords. Fortunately, finding an arbitrary triangulation is a fairly easy task, but what if you were asked to find the best triangulation according to some measure?

Input 

On the first line of the input is a single positive integer n, telling the number of test scenarios to follow. Each scenario begins with a line containing one positive integer 2 < m < 50, being the number of vertices of the simple polygon. The following m lines contain the vertices of the polygon in the order they appear along the border, going either clockwise or counter clockwise, starting at an arbitrary vertex. Each vertex is described by a pair of integers x y obeying 0 ≤ x ≤ 10 000 and 0 ≤ y ≤ 10 000.

Output 

For each scenario, output one line containing the area of the largest triangle in the triangu-lation of the polygon which has the smallest largest triangle. The area should be presented with one fractional decimal digit.

Sample Input 

167 06 29 53 50 31 1

Sample Output 

9.0
#include <cstdio>#include <cmath>#include <utility>#include <cstring>#include <algorithm>using namespace std;// 记录点pair<int,int> point[60];// 点的个数int n;// record[i][j]代表多边形i,i+1,...,j进行三角剖分最大三角形的最小面积 double record[55][55];// flag[i][j]代表record[i][j]是否被计算过int flag[55][55];double get_min(int i, int j);double get_area(int i, int j, int k);int main(){int t;scanf("%d", &t);int count = 0;while(count < t){memset(flag, 0, sizeof(flag));scanf("%d", &n);for(int i = 0; i < n; i++){scanf("%d %d", &point[i].first, &point[i].second);}// 计算结果printf("%.1f\n", get_min(0,n-1));count++;}return 0;}// 计算多边形:i,i+1,...,j三角剖分最大三角形的最小面积double get_min(int i, int j){if(flag[i][j] == 1)return record[i][j];if(i+1 == j){flag[i][j] = 1;record[i][j] = 0;return record[i][j];}record[i][j] = 1<<30;for(int k = i+1; k < j; k++){double area = get_area(i, j, k);// 首先需要保证i,j,k可围成三角形,即没有点在三角形内int m;for(m = 0; m < n; m++){if(m != i && m != j && m != k){double a1 = get_area(i, j, m);double a2 = get_area(i, k, m);double a3 = get_area(j, k, m);if(fabs((a1+a2+a3)-area) < 1e-5)break;}}if(m == n){double r = max(get_min(i,k), get_min(k,j));r = max(r, area);if(r < record[i][j])record[i][j] = r;}}flag[i][j] = 1;return record[i][j];}// 计算三点围成的三角形面积double get_area(int i, int j, int k){double a = sqrt((point[i].first-point[j].first)*(point[i].first-point[j].first)                                +(point[i].second-point[j].second)*(point[i].second-point[j].second));      double b = sqrt((point[i].first-point[k].first)*(point[i].first-point[k].first)                                +(point[i].second-point[k].second)*(point[i].second-point[k].second));double c = sqrt((point[k].first-point[j].first)*(point[k].first-point[j].first)                                +(point[k].second-point[j].second)*(point[k].second-point[j].second));      double p = (a+b+c)/2;    double area = sqrt(p*(p-a)*(p-b)*(p-c));return area;}


和最优三角剖分类似,对于多边形i,i+1,...,j来说,总要从i+1,...,j-1中选择一个点来形成三角形。以此进行状态表示及转移。
需要注意的是,此处没有规定多边形为凸多边形,有可能选择的三个点不能构成三角形,即有其他点在该三角形中。
判断点k是否在三角形abc中,可以用三角形面积abk+bck+ack是否等于abc来判断。
另外,这题WA了很久,发现是在主程序中另外定义了一个局部变量n. 以后需要注意局部变量和全局变量重名引起的错误。
0 0
原创粉丝点击