zoukankan      html  css  js  c++  java
  • 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]<<'
    ';
    }
    

    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;
    }
    
  • 相关阅读:
    给列表项标记添加自定义图像
    双飞翼布局与圣杯布局
    CSS3 calc()
    CSS滚动视差
    应用层层面面试题汇总
    Linux下OpenSSL 安装
    深入理解:Android 编译系统
    ios 好去处
    IBOutlet & IBAction
    ar技术序章-SDK介绍和选择
  • 原文地址:https://www.cnblogs.com/Yuhuger/p/13640654.html
Copyright © 2011-2022 走看看