2017-2018 ACM-ICPC East Central North America Regional Contest (ECNA 2017)部分题解

计划补J,B,I。
J题是一道简单的模拟题,但是训练的时候还是WA了。
分类一定要分清楚,不能没想清楚就上机,越上越乱。
J题代码

// 2020-09-08 20:56:35.545006 
#include <bits/stdc++.h>
using namespace std;
int tim[50],rest[50],usage[50];
int a[50],b[50];
int main(){
	int n=10;
	for (int i=1; i<=n; ++i) scanf("%d%d",&a[i],&b[i]);
	for (int i=n+1; i<=3*n; ++i){
		a[i]=a[(i-1)%n+1];
		b[i]=b[(i-1)%n+1];
	}
	for (int i=1; i<=n; ++i){
		scanf("%d%d%d",&usage[i],&rest[i],&tim[i]);
	}
	int nowtime=0;
	for (int i=1; i<=3*n; ++i){
		int id=(i-1)%n+1;
		//cerr<<"tim"<<tim[id]<<endl;
	    //case 1
	    if (nowtime<tim[id]){
	        tim[id]=max(nowtime+a[id],tim[id]);
	        nowtime+=a[id]+b[id];
	    }
	    else if ((nowtime-tim[id])%(usage[id]+rest[id])<usage[id]){
	        int tmp=(nowtime-tim[id])/(usage[id]+rest[id])*(usage[id]+rest[id])+tim[id];
	        tim[id]=tmp+usage[id]+rest[id];
	        tim[id]=max(tim[id],tmp+usage[id]+a[id]);
	        nowtime=tmp+usage[id]+a[id]+b[id];
	    }
	    else{
	        int tmp=(nowtime-tim[id])/(usage[id]+rest[id])*(usage[id]+rest[id])+tim[id];
	        tim[id]=tmp+usage[id]+rest[id];
	        tim[id]=max(tim[id],nowtime+a[id]);
	        nowtime+=a[id]+b[id];
	    }
	}
	cout<<nowtime-b[n]<<'\n';
}

B题是一道圆凸包题,做法就是找到最右边的圆,一定在凸包上,然后求出所有公切线,逐个旋转求出整个凸包,注意重圆和包含关系的处理
包含要去掉因为包含的圆算不了公切线。
代码

#include <bits/stdc++.h>
using namespace std;
const double pi=acos(-1);
double laangl;
struct point{
    double x,y;
    point(){
    }
    point(double x,double y):x(x),y(y){
    }
    bool operator !=(const point& _) const{
        return x!=_.x||y!=_.y;
    }
};
const double ang=0.3214324;
const double eps=1e-7;
point rotate(point x){
	return point(x.x*cos(ang)-x.y*sin(ang),x.x*sin(ang)+x.y*cos(ang));
}
double sqr(double x){
    return x*x;
}
double dis(point x,point y){
    return sqrt(sqr(x.x-y.x)+sqr(x.y-y.y));
}
double dis(double r,point x,point y){
	//cerr<<"X"<<x.x<<" "<<x.y<<endl;
	//cerr<<"Y"<<y.x<<" "<<y.y<<endl; 
    double angl=asin(dis(x,y)/2/r);
    //cerr<<"angl"<<angl<<" "<<dis(x,y)/2/r<<endl;
    return angl*2*r;
}
double fix(double x){
    while (x>=2*pi) x-=2*pi;
    while (x<0) x+=2*pi;
    return x;
}
struct line{
    point o;
    double ang;
    point drive(double x){
        return point(o.x+cos(ang)*x,o.y+sin(ang)*x);
    }
    line(point o,double ang):o(o),ang(ang){
    }
    void rotate(double x){
        ang=fix(ang+x);
    }
    bool operator <(const line &_) const{
		double x=ang,y=_.ang;
		x=fix(x-laangl);
		y=fix(y-laangl);
		if (abs(x-y)<eps) return 0;
		return x<y;
	}
};
const int N=210;
struct circle{
    point o;
    double r;
    pair<line,double> operator &(const circle &_) const{
        double dist=dis(o,_.o);
        double dr=_.r-r;
        double len=sqrt(sqr(dist)-sqr(dr));
        double angl=acos(dr/dist);
        double angl2=fix(pi/2-angl);
        line t(o,fix(atan2(_.o.y-o.y,_.o.x-o.x)));
        t.rotate(-angl2);
        line l=t;
        l.rotate(-pi/2);
        point tmp=l.drive(r);
        return make_pair(line(tmp,t.ang),len);
    }
    bool contain(const circle &_) const{
        return r-_.r+eps>=dis(o,_.o);
    }
}a[N];
int n;
bool ban[N];
void QBH(){
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=n; ++j)
            if (i!=j&&a[i].contain(a[j])) ban[j]=1;
    int cnt=0;
    for (int i=1; i<=n; ++i) if (!ban[i]) a[++cnt]=a[i];
    n=cnt;
}
double ans;
const point EMPTY=point(-2344,3455);
point la[N];
void solve(){
    QBH();
    //cerr<<n<<endl;
    if (n<=1){
    	ans=2*pi*a[1].r;
    	return;
	}
    int mx=1;
    for (int i=1; i<=n; ++i) if (a[i].r+a[i].o.x>a[mx].r+a[mx].o.x) mx=i;
    //cerr<<"MX"<<mx<<endl;
	int now=mx;
    laangl=0;
    for (int i=1; i<=n; ++i) la[i]=EMPTY;
    while (1){
    	//cerr<<"now"<<now<<" "<<ans<<endl; 
        vector<pair<pair<line,double>,int> > g;
        for (int i=1; i<=n; ++i) if (i!=now) g.push_back(make_pair(a[now]&a[i],i));
        sort(g.begin(),g.end());
		line tmp=g[0].first.first;
		laangl=tmp.ang;
        ans+=g[0].first.second;
        int nxt=g[0].second;
        if (la[now]!=EMPTY){
        	//cerr<<"HU"<<now<<endl;
			ans+=dis(a[now].r,la[now],tmp.o);
			la[now]=EMPTY;
			//cerr<<dis(a[now].r,la[now],tmp.o)<<endl;
		}
        else la[now]=tmp.o;
        if (la[nxt]!=EMPTY){
        	//cerr<<"HU"<<nxt<<endl;
        	ans+=dis(a[nxt].r,la[nxt],tmp.drive(g[0].first.second));
        	la[nxt]=EMPTY;
        	//cerr<<dis(a[nxt].r,la[nxt],tmp.drive(g[0].first.second))<<endl;
		}
		else la[nxt]=tmp.drive(g[0].first.second);
        now=nxt;
        if (now==mx) return;
    }
}
int main(){
    scanf("%d",&n);
    for (int i=1; i<=n; ++i){
		scanf("%lf%lf%lf",&a[i].o.x,&a[i].o.y,&a[i].r);
		a[i].r+=10;
	}
    solve();
    cout<<fixed<<setprecision(10)<<ans;
}
posted @ 2020-09-09 18:55  Yuhuger  阅读(266)  评论(0编辑  收藏  举报