test

#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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值