QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#399861#6752. Geometryericmegalovania#TL 0ms3904kbC++202.9kb2024-04-26 18:40:392024-04-26 18:40:40

Judging History

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

  • [2024-04-26 18:40:40]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3904kb
  • [2024-04-26 18:40:39]
  • 提交

answer

#include<bits/stdc++.h>//暴力划分,然后凸包
using namespace std;

//#define ONLINE
#ifndef ONLINE
#define debug(...) fprintf(stderr,##__VA_ARGS__)
#else
#define debug(...) ;
#endif

using LL=long long;
using PII=pair<int,int>;

#define eps (1e-12)
inline int sign(const double& x){
	if(fabs(x)<=eps) return 0;
	return x>0.0?1:-1;
}
inline int dcmp(const double& x,const double& y){
	return sign(x-y);
}

using PDD=pair<double,double>;
#define x first
#define y second
PDD operator -(const PDD& A,const PDD& B){
	return {A.x-B.x,A.y-B.y};
}
PDD operator +(const PDD& A,const PDD& B){
	return {A.x+B.x,A.y-B.y};
}
double operator *(const PDD& A,const PDD& B){
	return A.x*B.y-A.y*B.x;
}

bool check(const PDD& A,const PDD& B,const PDD& C){
	PDD P=B-A,Q=C-B;
	return sign(P*Q)==1;
}
double dis(const PDD& A,const PDD& B){
	PDD d=A-B;
	return sqrt(d.x*d.x+d.y*d.y);
}

template<typename T>
inline T READ(){
	T x=0; bool f=0; char c=getchar();
	while(c<'0' || c>'9') f|=(c=='-'),c=getchar();
	while(c>='0' && c<='9') x=x*10+c-'0',c=getchar();
	return f?-x:x;
}
inline int read(){return READ<int>();}
inline LL readLL(){return READ<LL>();}
mt19937 rng(chrono::system_clock::now().time_since_epoch().count());

#define N 20
int n;
PII a[N][3];

int top_opt=0,top[N];
int opt[N][N];

double ans=800.0;
PDD pos[N*3]; int top_pos;
int up[N*3],top_up=0,down[N*3],top_down=0;
inline double calc(){
	double res=0.0;
	for(int i=1;i<=top_opt;i++){
		top_pos=0;
		for(int j=1;j<=top[i];j++){
			pos[++top_pos]=a[opt[i][j]][0];
			pos[++top_pos]=a[opt[i][j]][1];
			pos[++top_pos]=a[opt[i][j]][2];
		}
		sort(pos+1,pos+top_pos+1,[](const PDD& A,const PDD& B){
			if(dcmp(A.y,B.y)==0) return dcmp(A.x,B.x)==-1;
			return dcmp(A.y,B.y)==-1;
		});
		up[top_up=1]=1;
		for(int i=2;i<=top_pos;i++){
			while(top_up>=2 && !check(pos[up[top_up-1]],pos[up[top_up]],pos[i])) top_up--;
			up[++top_up]=i;
		}
		down[top_down=1]=up[top_up];
		for(int i=top_pos-1;i>0;i--){
			while(top_down>=2 && !check(pos[down[top_down-1]],pos[down[top_down]],pos[i])) top_down--;
			down[++top_down]=i;
		}
		for(int i=1;i<top_up;i++) res+=dis(pos[up[i]],pos[up[i+1]]);
		for(int i=1;i<top_down;i++) res+=dis(pos[down[i]],pos[down[i+1]]);
	}
	return res;
}

void dfs(int u){
	if(u>n){
		ans=min(ans,calc());
		return;
	}
	++top_opt;
	opt[top_opt][top[top_opt]=1]=u;
	dfs(u+1);
	top[top_opt--]=0;
	for(int i=1;i<=top_opt;i++){
		opt[i][++top[i]]=u;
		dfs(u+1);
		top[i]--;
	}
}

int main(){
	n=read();
	for(int i=1;i<=n;i++){
		a[i][0].x=read(),a[i][0].y=read();
		a[i][1].x=read(),a[i][1].y=read();
		a[i][2].x=read(),a[i][2].y=read();
	}
	dfs(1);
	printf("%.12lf\n",ans);
	return 0;
}

/* stuff you should look for
* int overflow, array bounds
* special cases (n=1?)
* do smth instead of nothing and stay organized
* WRITE STUFF DOWN
* DON'T GET STUCK ON ONE APPROACH
*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

2
0 0 1 0 0 1
100 100 101 100 100 101

output:

6.828427124746

result:

ok found '6.82843', expected '6.82843', error '0.00000'

Test #2:

score: 0
Accepted
time: 0ms
memory: 3904kb

input:

2
0 0 0 1 1 0
1 0 0 1 1 1

output:

4.000000000000

result:

ok found '4.00000', expected '4.00000', error '0.00000'

Test #3:

score: -100
Time Limit Exceeded

input:

14
3 0 0 2 0 1
3 3 2 0 0 1
2 0 3 2 2 0
3 2 3 1 0 3
0 0 1 3 1 2
3 2 2 2 0 1
1 2 1 0 3 2
0 0 0 3 3 2
2 1 3 2 2 2
2 1 0 1 1 0
2 0 3 2 0 2
0 2 3 1 3 3
1 2 0 2 2 0
3 3 3 1 3 1

output:


result: