#include <iostream>
#include <math.h>
#include <algorithm>
#include <fstream>
using namespace std;
//Class of point.
class coordinates
{
public:
int order;//Record its original order when being input
double x, y;//Record its x,y coordinates
};
//A class that can keep both the value and where it comes from
class solution
{
public:
float value;//The maximum value
int track;//Here is the k that fits the maximum condition
};
double triField(coordinates &a, coordinates &b, coordinates &c)//Given 3 vertices and return the area
{
//Calculate 3 edges
double d_ab = sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
double d_ac = sqrt((a.x - c.x)*(a.x - c.x) + (a.y - c.y)*(a.y - c.y));
double d_bc = sqrt((b.x - c.x)*(b.x - c.x) + (b.y - c.y)*(b.y - c.y));
double p = (d_ab + d_bc + d_ac) / 2;
//Helen's Equation
return sqrt(p*(p - d_ab)*(p - d_bc)*(p - d_ac));
}
double jj(coordinates &point, coordinates ¢er)//Return the polar angle of point with respect to center
{
coordinates tmp;
//tmp records the relative coordinates
tmp.x = point.x - center.x;
tmp.y = point.y - center.y;
int phase;//Marks which phase point is in with respect to center
if ((tmp.x > 0) and (tmp.y > 0)) phase = 1;
if ((tmp.x < 0) and (tmp.y > 0)) phase = 2;
if ((tmp.x < 0) and (tmp.y < 0)) phase = 3;
if ((tmp.x > 0) and (tmp.y < 0)) phase = 4;
switch (phase)//Get the value of polar angle according to the phase and tangent
//Polar angel value is between (0, 2*PI)
{
case 1:
return atan(tmp.y / tmp.x);
case 2:
return 3.14159265358979 + atan(tmp.y / tmp.x);
case 3:
return 3.14159265358979 + atan(tmp.y / tmp.x);
case 4:
return 2 * 3.14159265358979 + atan(tmp.y / tmp.x);
default:
break;
}
}
int main()
{
coordinates set[301];//The points input
int N, n; //Parameters
cin >> N >> n;
double tot_x = 0, tot_y = 0;//To calculate a center
for (int i = 0; i < N; i++)
{
cin >> set[i].x >> set[i].y;
tot_x += set[i].x;
tot_y += set[i].y;
set[i].order = i;
}
coordinates center;//Center point
center.x = tot_x / N;
center.y = tot_y / N;
double angle[301];//The corresponding polar angle of every point
for (int i = 0; i < N; i++)
{
angle[i] = jj(set[i], center);//Get the polar angle
}
//Get the sorted anticlockwise point set.
//A naive sorting technique
for (int i = 0; i < N - 1; i++)
{
for (int j = i + 1; j < N; j++)
{
if (angle[i]>angle[j])
{
coordinates tmp = set[i];
set[i] = set[j];
set[j] = tmp;
double atmp = angle[i];
angle[i] = angle[j];
angle[j] = atmp;
}
}
}
solution s[300][300][10];//s[i][j][k] marks the largest area of a k-gon containing point i, (i+j)%N, and some other (k-2)
//points. The points have their order in anticlockwise.
int ans_i, ans_j;//Record the largest n-gon's i and j
double ans = 0;
for (int i = 0; i < N; i++)//A polygon has at least 3 edges. So we start from k=2
{
for (int j = 0; j < N; j++)
{
s[i][j][2].track = -1;//-1 marks the end of backtracking
s[i][j][2].value = 0;//0 is for the correctness of the algorithm
}
}
for (int i = 0; i < N; i++)//Take each point as a starting point
{
for (int in = 3; in <= n; in++)//Order. The number of edges
{
for (int j = in-1; j < N; j++)//The ending point. It is calculated circularly
{
double max;
max = 0;//Initialize maximum
int trace;
trace = -1;//Initialize trace
double tmp;
for (int k = 1; k < j; k++)//Search for all points in between
{
tmp = s[i][k][in - 1].value + triField(set[i], set[(i + k) % N], set[(i + j) % N]);//The state function
if (tmp > max)//If this is a new max, update.
{
max = tmp;
trace = k;
}
}
//Keep this track
s[i][j][in].track = trace;
s[i][j][in].value = max;
}
}
//One round of searching has ended. Now refresh our final answer.
//Find if there's any i,j tuple outweighs the current solution.
for (int j=n-1;j<N;j++)
{
if (s[i][j][n].value>ans)
{
ans=s[i][j][n].value;
ans_i=i;
ans_j=j;
}
}
}
//v is a flag array. If point i(input order) is deleted, then v[i]=1; else v[i]=0
int v[301] = { 0 };
//i and j is deleted
v[set[ans_i].order] = 1;
v[set[(ans_i + ans_j) % N].order] = 1;
//Initialize
int tr = s[ans_i][ans_j][n].track, ord=n;//tr keeps track of the point. ord is the order, telling the program the state.
//backtracking
while (tr != -1)//Until meets the ending flag -1
{
//Set the backtrack point as deleted
v[set[(ans_i + tr) % N].order] = 1;
//Backtrack deeper
tr = s[ans_i][tr][--ord].track;
}
int anss[300], cnt = 0;
//Save the answer in ascending order
for (int i = N - 1; i >= 0; i--)
{
if (v[i])
{
anss[cnt] = i;
cnt++;
}
}
//Output the answer
for (int i = 0; i < cnt - 1; i++)
{
cout << anss[i] << ' ';
}
cout << anss[cnt - 1];
return 0;
}
test
最新推荐文章于 2023-08-15 10:54:36 发布