玄关求调
查看原帖
玄关求调
137242
DiaоsiKreator楼主2024/5/22 21:28

第三个点挂了。。。

大概是有解被判成无解,D 不出来了

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef long double ld;
using namespace std;
const int N=500010,M=5000010,INF=0x3f3f3f3f;
const ld eps=1e-6,inf=1e18;
int T,n,m,t,flg,s[N],v[N],w[N],b[N];
ld ans1,ans2;
struct rec{int x,y,z;};
vector<rec> h;

struct node{
	ll x,y;
	node(ll xx=0,ll yy=0){x=xx,y=yy;}
	void in(){scanf("%lld%lld",&x,&y);}
}p[N],q[N];

node operator +(node a,node b){return node(a.x+b.x,a.y+b.y);}
node operator -(node a,node b){return node(a.x-b.x,a.y-b.y);}
ll operator *(node a,node b){return a.x*b.x+a.y*b.y;}
ll operator ^(node a,node b){return a.x*b.y-a.y*b.x;}

node operator *(ll x,node b){return node(x*b.x,x*b.y);}

node O(0,0),P(-1,0);
bool cmp1(node a,node b){return a.x!=b.x?a.x<b.x:a.y<b.y;}
bool cmp2(node a,node b){
	if((a^b)==0)return a.x<b.x;
    if(((P-O)^(a-O))==0&&(P.x-O.x)*(a.x-O.x)>0)return 1;
    if(((P-O)^(b-O))==0&&(P.x-O.x)*(b.x-O.x)>0)return 0;
    if((((P-O)^(a-O))>0)!=(((P-O)^(b-O))>0))return ((P-O)^(a-O))>((P-O)^(b-O));
    return ((a-O)^(b-O))>0;
}

ld sqr(ld x){return (ld)x*x;}
ld dis(node a,node b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}

ll chk(node a,node b,node c){
	return (b-a)^(c-b);
}

int pre(int i){return i==1?n:i-1;}
int nxt(int i){return i==n?1:i+1;}

bool check(){
	for(rec t:h)
		if(v[t.x]==v[t.y]&&v[t.x]==v[t.z])return 0;
	return 1;
}
ld solve1(){
	flg=0;
	int cnt=0,tot=0,cur=0;
	ld res=0;
	for(int i=1;i<=n;i++)q[i]=p[i];
	m=n+1;q[m]=node(0,0);
	//outer
	sort(q+1,q+m+1,cmp1);
	for(int i=1;i<=m;i++)v[i]=0;
	s[t=1]=1;
	for(int i=2;i<=m;i++){
		while(t>1&&chk(q[s[t-1]],q[s[t]],q[i])<0)t--;
		s[++t]=i;
	}
	for(int i=1;i<=t;i++){
		if(i>1)res+=dis(q[s[i-1]],q[s[i]]);
		v[s[i]]=1;
	}
	for(int i=1;i<=t;i++)b[++cur]=s[i];
	s[t=1]=1;
	for(int i=2;i<=m;i++){
		while(t>1&&chk(q[s[t-1]],q[s[t]],q[i])>0)t--;
		s[++t]=i;
	}
	for(int i=1;i<=t;i++){
		if(i>1)res+=dis(q[s[i-1]],q[s[i]]);
		v[s[i]]=1;
	}
	for(int i=t-1;i>1;i--)b[++cur]=s[i];
	for(int i=1;i<=m;i++){
		if(v[i]&&!q[i].x&&!q[i].y)w[++cnt]=i,flg=1;
		if(v[i])continue;
		if(!q[i].x&&!q[i].y)return 0;
		w[++cnt]=i;
	}
	//inner
	s[t=1]=w[1];
	for(int i=2;i<=cnt;i++){
		while(t>1&&chk(q[s[t-1]],q[s[t]],q[w[i]])>=0)t--;
		s[++t]=w[i];
	}
	for(int i=1;i<=t;i++){
		if(i>1)res+=dis(q[s[i-1]],q[s[i]]);
		v[s[i]]=2;
	}
	s[t=1]=w[1];
	for(int i=2;i<=cnt;i++){
		while(t>1&&chk(q[s[t-1]],q[s[t]],q[w[i]])<=0)t--;
		s[++t]=w[i];
	}
	for(int i=1;i<=t;i++){
		if(i>1)res+=dis(q[s[i-1]],q[s[i]]);
		v[s[i]]=2;
	}
	for(int i=1;i<=m;i++){
		if(!v[i])return 0;
		tot+=(v[i]==2);
	}
	if(tot<3)return 0;
	for(int i=1;i<=cur;i++)
		if(!chk(q[b[i==1?cur:i-1]],q[b[i]],q[b[i==cur?1:i+1]]))return 0;
	return res;
}
ld solve2(){
	ld res=0,tmp=0;
	h.clear();
	sort(p+1,p+n+1,cmp2);
	for(int i=1;i<=n;i++)v[i]=0;
	for(int i=1;i<=n;i++){
		if(chk(p[pre(i)],p[i],p[nxt(i)])<=0)h.pb((rec){pre(i),i,nxt(i)});
		if(!(p[i]^p[nxt(i)]))return 0;
	}
	if(h.size()>4)return 0;
	if(flg){
		int flag=0,j=1;
		p[0]=node(0,0);
		for(int i=1;i<=n;i++)
			if((p[i]^p[nxt(i)])<0)j=nxt(i);
		for(int i=1,k=j;i<=n;i++,k=nxt(k))
			tmp+=dis(p[k],p[nxt(k)]);
		tmp-=dis(p[pre(j)],p[j]);
		tmp+=dis(p[0],p[j]);
		tmp+=dis(p[0],p[pre(j)]);
		v[j]=1;j=nxt(j);
		for(int i=2;i<n-1;i++,j=nxt(j)){
			v[j]=1;
			if(!check())continue;
			flag=1;
			res=max(res,tmp+dis(p[0],p[j])+dis(p[0],p[nxt(j)])-dis(p[j],p[nxt(j)]));
		}
		if(flag)return res;
		return 0;
	}
	for(int i=1;i<=n;i++)tmp+=dis(p[i],p[nxt(i)]);
	v[1]=1;
	for(int i=1,j=1,k=1;i<=n;i++,k--){
		while((p[i]^p[nxt(j)])>0){
			j=nxt(j),v[j]=1,k++;
			if(!check()||n-k<2||(p[nxt(j)]^p[pre(i)])<=0)continue;
			res=max(res,tmp-dis(p[pre(i)],p[i])-dis(p[j],p[nxt(j)])
				+dis(p[0],p[i])+dis(p[0],p[j])+dis(p[0],p[pre(i)])+dis(p[0],p[nxt(j)]));
		}
		v[i]=0;
	}
	return res;
}
void solve(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)p[i].in();
	ans1=solve1();
	ans2=solve2();
	printf("%.10Lf\n",max(ans1,ans2));
}
int main(){
	scanf("%d",&T);
	while(T--)solve();
	return 0;
}
2024/5/22 21:28
加载中...