您的位置:首页 > 其它

ACM: 计算几何题 poj 2066

2016-05-19 23:26 295 查看
Minimax
Triangulation
 

Description

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
triangulation of the polygon which has the smallest largest
triangle. The area should be presented with one fractional decimal
digit.
Sample Input

1

6

7 0

6 2

9 5

3 5

0 3

1 1

Sample Output

9.0

 

题意: 将多边形分割成m-2个三角形, 通过不相邻的m-3条对角线分成的, 现在要你求出分割之后,

     
相应的分割形成的最大三角形的面积最小. 输出它的面积.(最大又要最小的读题几遍才明白)

 

解题思路:

    
1. 先提一提以前遇到的一个问题, 同样是分割多边形成m-2个三角形, 求的是所有三角形面积

        和最大.
方程: dp[i][j] = max(dp[i][k]+dp[k][j]+area(i,j,k));

    
2. 这题是求分割之后的最大三角形面积最小, 设dp[i][j]表示顶点i到顶点j的最大三角的最小

       
面积.

       
问题分析: (分割线是不想交的, 下列才成立)

       
(1). 初始化: dp[i][i+2] = area(p[i], p[i+1], p[i+2]);

        (2).
方程的转移: 假设i<j

            
情况一: 从i到j中间存在一个顶点k满足, area(p[i], p[j], p[k])是面积最大的.

                    
temp1 = max(area(p[i], p[j], p[k]), dp[i][k], dp[k][j]);

            
情况二: 在顶点i+1到j的范围内, 添加一个顶点i, area(p[i], p[i+1], p[j]);

                    
temp2 = max(area(p[i], p[i+1], p[k]), dp[i+1][j]);

            
情况三: 在顶点i到j-1的范围内, 添加一个顶点j, area(p[i], p[j-1], p[j]);

                    
temp3 = max(area(p[i], p[j-1], p[j]), dp[i][j-1]);

            
最后, 综合前面求出的顶点i到顶点j的范围内最大的三角形面积, 求最小值即可.

             dp[i][j]
= min(temp1, temp2, temp3);

            
(因为分割线不相交的, 所以上述可以求面积area, 三个内不存在其它顶点);

    3.
面积用向量来求, 避免使用海伦公式.

代码:

#include <cstdio>

#include <iostream>

#include <cstring>

#include <cmath>

using namespace std;

#define MAX 55

const int INF = (1<<30);

struct node

{

 int x, y;

}p[MAX];

int n;

int dp[MAX][MAX];

inline int max(int a, int b)

{

 return a > b ? a : b;

}

inline int min(int a, int b)

{

 return a < b ? a : b;

}

inline int multiply(node A, node B)

{

 return A.x*B.y - A.y*B.x;

}

inline int area(node A, node B, node C)

{

 int size = multiply(A, B)+multiply(B,
C)+multiply(C, A);

 return size > 0 ? size :
(-size);

}

inline bool judge(int i, int j, int k)

{

 int size = area(p[i], p[j], p[k]);

 for(int t = 1; t <= n; ++t)

 {

  if(t == i || t == j || t == k)
continue;

  int temp = area(p[i], p[j],
p[t])+area(p[i], p[k], p[t])+area(p[j], p[k], p[t]);

  if(size == temp) return
false;

 }

 return true;

}

int main()

{

 int i, j, k;

// freopen("input.txt", "r", stdin);

 int caseNum;

 scanf("%d", &caseNum);

 while(caseNum--)

 {

  scanf("%d",
&n);

  for(i = 1; i <=
n; ++i)

   scanf("%d
%d", &p[i].x, &p[i].y);

   

  memset(dp, 0,
sizeof(dp));

  for(i = 1; i <=
n-2; ++i)

   dp[i][i+2] =
area(p[i], p[i+1], p[i+2]);

   

  int temp1, temp2, temp3;

  for(int q = 3; q
< n; ++q)

  {

   for(i = 1;
i+q <= n; ++i)

   {

    j
= i+q;

    temp1
= INF;

    if(
judge(i, i+1, j) )

     temp1
= max(area(p[i], p[i+1], p[j]), dp[i+1][j]);

    if(
judge(i, j-1, j) )

    {

     temp2
= max(area(p[i], p[j-1], p[j]), dp[i][j-1]);

     temp1
= min(temp1, temp2);

    }

    for(k
= i+2; k <= j-2; ++k)

    {

     if(
!judge(i, j, k) ) continue;

     temp2
= area(p[i], p[j], p[k]);

     temp3
= dp[i][k];

     temp2
= max(temp2, temp3);

     temp3
= dp[k][j];

     temp2
= max(temp2, temp3);

     

     temp1
= min(temp1, temp2);

    }

    dp[i][j]
= temp1;

   }

  }

  

  printf("%d", dp[1]
/2);

  if(dp[1]
% 2 == 1)
printf(".5\n");

  else printf(".0\n");

 }

 

 return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: