QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#197883 | #5809. Min Perimeter | zhouhuanyi | 0 | 0ms | 0kb | C++23 | 2.7kb | 2023-10-02 21:12:11 | 2023-10-02 21:12:11 |
answer
#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<algorithm>
#include<vector>
#include<cmath>
#include<random>
#define N 1000000
#define M 1048575
#define eps 1e-9
using namespace std;
mt19937 RAND(random_device{}());
int read()
{
char c=0;
int sum=0;
while (c<'0'||c>'9') c=getchar();
while ('0'<=c&&c<='9') sum=sum*10+c-'0',c=getchar();
return sum;
}
struct points
{
int x,y;
bool operator != (const points &t)const
{
return x!=t.x||y!=t.y;
}
};
points st[N+1];
double dist(points a,points b)
{
return sqrt(1ll*(a.x-b.x)*(a.x-b.x)+1ll*(a.y-b.y)*(a.y-b.y));
}
struct node
{
int x,y,data,nxt;
};
node edge[N+1];
int T,n,len,dx[N+1],dy[N+1],head[M+1],length,tong[N+1],leng;
double ans,tans;
vector<points>v[N+1];
void add(int x,int y,int d)
{
int ds=(x+y)&M;
edge[++len]=(node){x,y,d,head[ds]},head[ds]=len,tong[++leng]=ds;
return;
}
int query(int x,int y)
{
int ds=(x+y)&M;
for (int i=head[ds];i>0;i=edge[i].nxt)
if (edge[i].x==x&&edge[i].y==y)
return edge[i].data;
return -1;
}
void build(int x,double d)
{
int ps;
for (int i=1;i<=leng;++i) head[tong[i]]=0;
len=length=leng=0;
for (int i=1;i<=x;++i)
{
dx[i]=(int)(floor(st[i].x/d)),dy[i]=(int)(floor(st[i].y/d)),ps=query(dx[i],dy[i]);
if (ps==-1) add(dx[i],dy[i],++length),ps=length,v[length].clear();
v[ps].push_back(st[i]);
}
return;
}
int main()
{
bool opt;
int ps,ps2;
T=read();
for (int qt=1;qt<=T;++qt)
{
len=leng=ans=0;
for (int i=0;i<=M;++i) head[i]=0;
n=read();
for (int i=1;i<=n;++i) st[i].x=read(),st[i].y=read();
shuffle(st+1,st+n+1,RAND),ans=dist(st[1],st[2])+dist(st[1],st[3])+dist(st[2],st[3]),build(3,ans);
for (int i=4;i<=n;++i)
{
opt=0,tans=ans;
for (int op=-1;op<=1;++op)
for (int op2=-1;op2<=1;++op2)
if (query(dx[i]+op,dy[i]+op2)!=-1)
{
ps=query(dx[i]+op,dy[i]+op2);
for (int op3=-1;op3<=1;++op3)
for (int op4=-1;op4<=1;++op4)
if ((op<op3||(op==op3&&op2<=op4))&&query(dx[i]+op3,dy[i]+op4)!=-1)
{
ps2=query(dx[i]+op3,dy[i]+op4);
for (int j=0;j<v[ps].size();++j)
for (int k=0;k<v[ps2].size();++k)
if (v[ps][j]!=v[ps2][k]&&dist(st[i],v[ps][j])+dist(st[i],v[ps2][k])+dist(v[ps][j],v[ps2][k])+eps<ans)
ans=dist(st[i],v[ps][j])+dist(st[i],v[ps2][k])+dist(v[ps][j],v[ps2][k]),opt=1;
}
}
if (opt) build(i,ans);
else
{
ps=query(dx[i],dy[i]);
if (ps==-1) add(dx[i],dy[i],++length),ps=length,v[length].clear();
v[ps].push_back(st[i]);
}
}
printf("Case #%d: %0.9lf\n",qt,ans);
}
return 0;
}
詳細信息
Subtask #1:
score: 0
Time Limit Exceeded
Test #1:
score: 0
Time Limit Exceeded
input:
15 3 2 6 7 0 3 0 3 713 269 371 79 455 421 3 91983245 637281504 756917015 312173515 869576338 436726680 10000 14761642 78236002 9047458 47951098 5238002 27761162 476182 2523742 1428546 7571226 26190010 138805810 21904372 116092132 18094916 95902196 43332562 229660522 55237112 292754072 52380020 27761...
output:
result:
Subtask #2:
score: 0
Time Limit Exceeded
Test #2:
score: 0
Time Limit Exceeded
input:
15 3 501691275 344354353 167768963 536043860 249445040 557426549 4 1000000000 0 0 0 1000000000 1000000000 0 1000000000 1000000 138925776 669369648 61257680 295150640 170762328 822763944 55483472 267329456 97736936 470914328 84041848 404928904 18463588 88960924 124429360 599523280 95066048 458045504 ...