QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#187569#3858. Systematic salesmanDaasWA 0ms30540kbC++142.9kb2023-09-24 18:11:422023-09-24 18:11:42

Judging History

你现在查看的是最新测评结果

  • [2023-09-24 18:11:42]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:30540kb
  • [2023-09-24 18:11:42]
  • 提交

answer

#include <bits/stdc++.h>
#define mp make_pair
#define double long double
using namespace std;
typedef pair<int,int> pii;
const double INF=1000000000000000,eps=1e-8;
const int W=12,N=1024;
double tmp[N][N],f[W+1][N][N];
int n;
struct point{
	int x,y,idn;
}a[N];
bool cmp0(point x,point y){
	return x.x<y.x;
}
bool cmp1(point x,point y){
	return x.y>y.y;
}
double dis(point x,point y){
	return sqrt(1.0*(x.x-y.x)*(x.x-y.x)+1.0*(x.y-y.y)*(x.y-y.y));
}
void solve(int L,int R,int now){
	if (L==R){
		f[now][L][R]=0;
		return;
	}
	if (now%2==0) std::sort(a+L,a+R+1,cmp0);
	else std::sort(a+L,a+R+1,cmp1);
	int mid=(L+R)>>1;
	solve(L,mid,now+1);
	solve(mid+1,R,now+1);
	if (L+1==R){
		f[now][L][R]=dis(a[L],a[R]);
		return;
	}
	if (L+2==R){
		f[now][L][R]=f[now+1][L][L+1]+dis(a[L+1],a[R]);
		f[now][L+1][R]=f[now+1][L][L+1]+dis(a[L],a[R]);
		return;
	}
	
	int midl=(L+mid)>>1,midr=(mid+1+R)>>1;
	for (int i=L;i<=mid;i++)
		for (int j=mid+1;j<=R;j++)
			tmp[i][j]=INF;
	for (int i=L;i<=midl;i++){
		for (int j=midl+1;j<=mid;j++)
			for (int k=mid+1;k<=R;k++){
				double tt=f[now+1][i][j]+dis(a[j],a[k]);//i-j-k
				tmp[i][k]=min(tmp[i][k],tt);
				tt=f[now+1][i][j]+dis(a[i],a[k]);//j-i-k
				tmp[j][k]=min(tmp[j][k],tt);
			}
	}
	for (int i=L;i<=mid;i++)
		for (int j=mid+1;j<=midr;j++)
			for (int k=midr+1;k<=R;k++){
				//i->tran[i][j]->j->k
				double tt=tmp[i][j]+f[now+1][j][k];
				f[now][i][k]=min(f[now][i][k],tt);
				//i->tran[i][k]->k->j
				tt=tmp[i][k]+f[now+1][j][k];
				f[now][i][j]=min(f[now][i][j],tt);
			}
}
double calc(int st,int k,int w,int ed,int now){
	return f[now][st][k]+f[now][w][ed]+dis(a[k],a[w]);
}
void pri(int L,int R,int st,int ed,int now){
	if (L==R){
		printf("%d ",a[L].idn);
		return;
	}
	if (L+1==R){
		printf("%d %d ",a[st].idn,a[ed].idn);
		return;
	}
	int mid=(L+R)>>1;
	//st->k->w->ed
	if (st<ed){
		for (int i=L;i<=mid;i++)
			for (int j=mid+1;j<=R;j++){
				if (fabs(calc(st,i,j,ed,now+1)-f[now][st][ed])<eps){
					pri(L,mid,st,i,now+1);
					pri(mid+1,R,j,ed,now+1);
					return;
				}		
			}	
	}else{
		for (int i=mid+1;i<=R;i++)
			for (int j=L;j<=mid;j++){
				if (fabs(calc(st,i,j,ed,now+1)-f[now][st][ed])<eps){
					pri(mid+1,R,st,i,now+1);
					pri(L,mid,j,ed,now+1);
					return;
				}
			}
	}
	
}
int main(){
	scanf("%d",&n);
	if(n==1)
	{
		puts("0");
		puts("1");
		return 0;
	}
	for (int i=1;i<=n;i++){
		scanf("%d%d",&a[i].x,&a[i].y);
		a[i].idn=i;
	}
	for (int w=0;w<=W;w++)
		for (int i=1;i<=n;i++)
			for (int j=1;j<=n;j++)
				f[w][i][j]=f[w][i][j]=INF;
	solve(1,n,0);
	double Ans=INF;
	pii gans;
	int mid=(1+n)>>1,st,ed;
	for (int i=1;i<=mid;i++)
		for (int j=mid+1;j<=n;j++)
			if (f[0][i][j]<Ans){
				Ans=f[0][i][j];
				st=i,ed=j;
			} 
	printf("%.8Lf\n",Ans);
	for (int w=0;w<=W;w++)
		for (int i=1;i<=n;i++)
			for (int j=i+1;j<=n;j++)
				f[w][j][i]=f[w][i][j];

	pri(1,n,st,ed,0);
	return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 30540kb

input:

8
7 3
2 0
4 5
1 4
8 2
9 9
0 8
6 1

output:

26.38332577
7 3 4 2 8 5 1 6 

result:

ok correct!

Test #2:

score: -100
Wrong Answer
time: 0ms
memory: 30412kb

input:

20
4 71
52 7
49 15
59 83
12 9
46 6
74 44
89 50
32 10
82 58
11 33
78 72
27 49
64 75
97 0
38 46
91 54
8 70
18 61
79 92

output:

428.88485203
1 18 19 13 16 5 11 9 6 3 2 7 8 15 17 10 20 12 14 4 

result:

wrong answer The first line of your output is 428.884852, but the length of jury's solution is 374.883681