求调圣诞树,代码好看(10pts)玄关
查看原帖
求调圣诞树,代码好看(10pts)玄关
727173
May_Cry_楼主2025/6/23 09:47

只过了性质 B,感觉没错啊?

#include<bits/stdc++.h>
using namespace std;
const int QAQ=2002;
double o1=-2e18;
int n,o2,da[QAQ],cun;
struct xxx {int x,y,z;} g[QAQ][QAQ][2],shi;
double f[QAQ][QAQ][2];
struct dian{double x,y,id;} d[QAQ];
double dis(int o1,int o2) {return (d[o1].x-d[o2].x)*(d[o1].x-d[o2].x)+(d[o1].y-d[o2].y)*(d[o1].y-d[o2].y);}
bool cmp(dian a,dian b) {return a.x<b.x;}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>d[i].x>>d[i].y,d[i].id=i;
	for(int i=1;i<=n;i++) if(d[i].y>o1) o1=d[i].y,o2=i;
	cout<<d[o2].id<<" ";
	for(int i=n+1;i<=n+n;i++) d[i]=d[i-n];
	for(int l=1;l<=n*2;l++) for(int r=1;r<=n*2;r++) f[l][r][0]=f[l][r][1]=1e18;
	f[o2][o2][0]=f[o2][o2][1]=f[o2+n][o2+n][0]=f[o2+n][o2+n][1]=0;
	for(int len=2;len<=n;len++)
		for(int l=1,r;l<=n*2;l++)
		{
			r=l+len-1;
			if(r>2*n) break;
			double a[6]={0,f[l+1][r][0]+dis(l,l+1),f[l+1][r][1]+dis(r,l),f[l][r-1][0]+dis(l,r),f[l][r-1][1]+dis(r-1,r)};
			if(a[1]<a[2]) f[l][r][0]=a[1],g[l][r][0]={l+1,r,0};
			else f[l][r][0]=a[2],g[l][r][0]={l+1,r,1};
			if(a[3]<a[4]) f[l][r][1]=a[3],g[l][r][1]={l,r-1,0};
			else f[l][r][1]=a[4],g[l][r][1]={l,r-1,1};
		}
	o1=2e18;
	for(int i=1;i<=n;i++)
	{
		if(f[i][i+n-1][0]<o1) o1=f[i][i+n-1][0],shi={i,i+n-1,0};
		if(f[i][i+n-1][1]<o1) o1=f[i][i+n-1][1],shi={i,i+n-1,1};
	}
	int l=shi.x,r=shi.y,s=shi.z;
	while(g[l][r][s].x!=0) da[++cun]=(s?d[r].id:d[l].id),l=g[l][r][s].x,r=g[l][r][s].y,s=g[l][r][s].z;
	while(cun) cout<<da[cun--]<<" ";
	return 0;
}
2025/6/23 09:47
加载中...