QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#187514 | #3858. Systematic salesman | Daas# | WA | 2ms | 30664kb | C++14 | 3.3kb | 2023-09-24 17:54:18 | 2023-09-24 17:54:18 |
Judging History
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);
//printf("::%d %d %d\n",L,R,now);
//for (int i=L;i<=R;i++) printf("%d ",a[i].idn);
//puts("");
int mid=(L+R)>>1;
solve(L,mid,now+1);
solve(mid+1,R,now+1);
//printf("::%d %d %d\n",L,R,now);
//for (int i=L;i<=R;i++) printf("%d ",a[i].idn);
//puts("");
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;
//f[i][j]+dis(j,k)+f[k][w]
//tmp[i][k]->min(f[i][j]+dis(j,k)
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
if (tt<tmp[i][k]){
tmp[i][k]=tt;
}
tt=f[now+1][i][j]+dis(a[i],a[k]);//j-i-k
if (tt<tmp[j][k]){
tmp[j][k]=tt;
}
}
}
//f[type][i][j]=min(tmp[i][k]+f[k][w])
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];
if (tt<f[now][i][k]){
f[now][i][k]=tt;
}
//i->tran[i][k]->k->j
tt=tmp[i][k]+f[now+1][j][k];
if (tt<f[now][i][j]){
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){
//cerr<<"?? "<<st<<" "<<ed<<"\n";
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;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 30588kb
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: 30664kb
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