5122: Polyline Simplification
时间限制: 5 Sec 内存限制: 128 MB提交: 32 解决: 9
[ 提交][ 状态][ 讨论版][命题人: admin]
题目描述
Mapping applications often represent the boundaries of countries, cities, etc. as polylines, which are connected sequences of line segments. Since fine details have to be shown when the user zooms into the map,these polylines often contain a very large number of segments. When the user zooms out, however, these fine details are not important and it is wasteful to process and draw the polylines with so many segments. In this problem, we consider a particular polyline simplification algorithm designed to approximate the original polyline with a polyline with fewer segments.
A polyline with n segments is described by n + 1 points p0 = (x0, y0),... , pn = (xn, yn), with the ith line segment being . The polyline can be simplified by removing an interior point pi (1≤i≤n-1),so that the line segments are replaced by the line segment . To select the point to be removed, we examine the area of the triangle formed by pi-1, pi, and pi+1 (the area is 0 if the three points are colinear), and choose the point pi such that the area of the triangle is smallest. Ties are broken by choosing the point with the lowest index. This can be applied again to the resulting polyline, until the desired number m of line segments is reached.
Consider the example below.
The original polyline is shown at the top. The area of the triangle formed by p2, p3, and p4 is considered (middle), and p3 is removed if the area is the smallest among all such triangles. The resulting polyline after p3 is removed is shown at the bottom.
A polyline with n segments is described by n + 1 points p0 = (x0, y0),... , pn = (xn, yn), with the ith line segment being . The polyline can be simplified by removing an interior point pi (1≤i≤n-1),so that the line segments are replaced by the line segment . To select the point to be removed, we examine the area of the triangle formed by pi-1, pi, and pi+1 (the area is 0 if the three points are colinear), and choose the point pi such that the area of the triangle is smallest. Ties are broken by choosing the point with the lowest index. This can be applied again to the resulting polyline, until the desired number m of line segments is reached.
Consider the example below.
输入
The first line of input contains two integers n (2≤n≤200 000) and m (1≤m < n). The next n+1 lines specify p0,..., pn. Each point is given by its x and y coordinates which are integers between -5000 and 5000 inclusive. You may assume that the given points are strictly increasing in lexicographical order. That is, xi < xi+1, or xi = xi+1 and yi < yi+1 for all 0≤i < n.
输出
Print on the kth line the index of the point removed in the kth step of the algorithm described above (use the index in the original polyline).
样例输入
10 7
0 0
1 10
2 20
25 17
32 19
33 5
40 10
50 13
65 27
75 22
85 17
样例输出
1
9
6
提示
来源
英文阅读理解题
题意:给你n+1个点,让你剩下m+1个点 。
删除的方法是,取出来构成最小三角形的中间点,去除那个点,最后输出去除点的顺序。
解法:先求出来每个三角形的面积,用set 排序或者用优先队列 都OK 每次取出来最小值Pop 并且更新左右点
两端点需要特殊处理下
#include<bits/stdc++.h>
using namespace std;
struct node{
int index;
int Are;
bool operator < (const node b) const{
if(Are==b.Are)
return index<b.index;
return Are<b.Are;
}
};
int area[200005];//存储面积
int x[200005]; //存储坐标
int y[200005];
int Left[200005]; //存储左右点
int Right[200005];
set<node>ss;
int getArea(int i) //叉积 求面积 2倍
{
int p1=i,p2=Left[i],p3=Right[i];
return abs(x[p1]*y[p2]+x[p2]*y[p3]+x[p3]*y[p1]-x[p1]*y[p3]-x[p2]*y[p1]-x[p3]*y[p2]);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int k=n-m;
for(int i=0;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
Left[n]=n-1;
Right[0]=1;
for(int i=1;i<n;i++)
{
Left[i]=i-1;
Right[i]=i+1;
area[i]=getArea(i);
node temp;
temp.Are=area[i];
temp.index=i;
ss.insert(temp);
}
for(int i=1;i<=k;i++)
{
set<node>::iterator it;
it=ss.begin();
int p=(*it).index;
ss.erase(it);
Left[Right[p]]=Left[p];
Right[Left[p]]=Right[p];
if(Left[p]!=0)
{
node temp;
temp.Are=area[Left[p]];
temp.index=Left[p];
it=ss.find(temp);
ss.erase(it);
area[Left[p]]=getArea(Left[p]);
temp.Are=area[Left[p]];
temp.index=Left[p];
ss.insert(temp);
}
if(Right[p]!=n)
{
node temp;
temp.Are=area[Right[p]];
temp.index=Right[p];
it=ss.find(temp);
ss.erase(it);
area[Right[p]]=getArea(Right[p]);
temp.Are=area[Right[p]];
temp.index=Right[p];
ss.insert(temp);
}
printf("%d\n",p);
}
return 0;
}