其他分享
首页 > 其他分享> > P3680 [CERC2016]凸轮廓线 Convex Contour 题解

P3680 [CERC2016]凸轮廓线 Convex Contour 题解

作者:互联网

差不多是凸包的板子题,十(fei)分(chang)的(du)水(liu)。。。

40pts做法:

将矩形的四点,三角形的三点,圆形的上下两端各一点加入点阵,用 Andrew 算法求凸包即可。
对于圆出现在队列某一段的情况,要特别判断。

100pts做法:

其实只需要将40pts做法做两个改动即可:


下面是我的源代码:

#include <bits/stdc++.h>
#define ll long long
#define rgi register int
using namespace std;
const int M=1e7+7;
inline int read(){
	int w=0,r=1;char c=getchar();
	while(!(isdigit(c)||c=='0'))c=getchar();
	if(c=='-')r=-1,c=getchar(); 
	while(isdigit(c))w=w*10+c-'0',c=getchar();
	return w*r;
}
int n,m,used[M],stk[M],cnt;
char c[M];
double pi=3.141592653,x,ans;
struct pt{
	double x,y;
}p[M];
void add(double x,double y){
	p[++m]=(pt){x,y};
}
bool operator <(pt aa,pt bb){
	return aa.x<bb.x||(aa.x==bb.x&&aa.y<bb.y);
}
pt operator -(pt aa,pt bb){
	return (pt){aa.x-bb.x,aa.y-bb.y};
}
double operator *(pt aa,pt bb){
	return aa.x*bb.y*1.000000000-bb.x*aa.y*1.000000000;
}
double d(int x,int y){
	return (double)sqrt(fabs(p[x].x-p[y].x)*fabs(p[x].x-p[y].x)*1.000000000+fabs(p[x].y-p[y].y)*fabs(p[x].y-p[y].y)*1.000000000);
}
int main(){
	n=read();
	scanf("%s",c+1);
	if(n==1){
		if(c[1]=='C')printf("%f\n",pi);
		else if(c[1]=='S')printf("%f\n",4.000000000);
		else if(c[1]=='T')printf("%f\n",3.000000000); 
		return 0;
	}
	for(int i=1;i<=n;i++,x+=1.000000000){
		if(c[i]=='C'){
			//if(i==1||i==n){
			//	ans=ans-1.000000000+pi/2.000000000;
			//}
			//add(x+0.500000000,0.000000000),add(x+0.500000000,1.000000000);
			for(double j=0.000000000;j<=1.000000000;j+=0.000100000){
				double xx=sqrt(0.250000000-fabs(j-0.500000000)*fabs(j-0.500000000)),x1=x+0.500000000-xx,x2=x+0.500000000+xx;
				add(x1,j),add(x2,j);
			}
		}else if(c[i]=='S'){
			add(x,0.000000000),add(x,1.000000000);
			add(x+1.000000000,0.000000000),add(x+1.000000000,1.000000000);
		}else{
			add(x,0.000000000),add(x+1.000000000,0.000000000);
			add(x+0.500000000,(double)sqrt(0.750000000));
		}
	}
	sort(p+1,p+m+1);
	stk[++cnt]=1; 
	for(int i=2;i<=m;i++){
		while(cnt>=2&&(p[stk[cnt]]-p[stk[cnt-1]])*(p[i]-p[stk[cnt]])<=0.000000)used[stk[cnt--]]=0;
		used[stk[++cnt]=i]=1;
	}
	int dn=cnt;
	for(int i=m-1;i;i--)if(!used[i]){
		while(cnt>=2&&(p[stk[cnt]]-p[stk[cnt-1]])*(p[i]-p[stk[cnt]])<=0.000000)used[stk[cnt--]]=0;
		used[stk[++cnt]=i]=1;
	}
	for(int i=1;i<=cnt;i++){
		int a=stk[i],b=stk[(i%cnt)+1];
		ans+=d(a,b)*1.000000000;
	}
	printf("%.9lf\n",ans);
	return 0;
} 
/*
4
TSTC
*/

标签:cnt,double,int,题解,40pts,stk,CERC2016,Convex,getchar
来源: https://www.cnblogs.com/wcy2006/p/15058479.html