• 2018-2019 ICPC Northwestern European Regional Programming Contest (NWERC 2018)


    C. Circuit Board Design

    题意:给你一棵有n个节点的树,要你在一个二维平面用n个点表示出这棵树,使得边的大小为1,边与边之间不能交叉,点不能重合。

    槽点:1、比赛时th的值设为了2*pi/n导致wa3..wa3..wa3..wa到自闭

    得设为pi/n的原因是不让儿子返回到父亲的方向导致边交叉

    2、题解好像说点输出要多输出小数点后几位,但是因为最开始就是输出10位所以没出现关于这个的问题

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e4+5;
    const int MAX=4e6+9;
    const int mod=1e9+7;
    const double ep1=1e-7;
    const double ep2=1e-3;
    const double pi=acos(-1);
    #define pb push_back
    /*
    因为边距离为1所以也可以把向量旋转写成a.x+cos(ang),a.y+sin(ang)
    */
    struct point{
        double x,y;
        point(){}
        point(double x,double y):x(x),y(y){}
    }p[maxn],ans[maxn];
    point operator-(point a,point b)
    {
        return point(a.x-b.x,a.y-b.y);
    }
    
    //p代表该点与父亲的向量,ans记录这个点的位置 
    #define Vector point
    Vector Rotate(Vector a,double rad)
    {
        return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
    }
    vector<int>vec[maxn];
    int n;
    int siz[maxn];
    double th; 
    void dfs(int x,int pre)//可以只用一个dfs,但是最开始这么写了就懒得改了
    {
        int si=vec[x].size();
        for(int i=0;i<si;i++)
        {
            int to=vec[x][i];
            if(to==pre)continue;
            dfs(to,x);
            siz[x]+=siz[to];
        }
        siz[x]++;
    }
    void dfs1(int x,int pre)
    {
        int si=vec[x].size();
        Vector v=p[x];
        point pp;
        for(int i=0;i<si;i++)
        {
            int to=vec[x][i];
            if(to==pre)continue;
            pp.x=ans[x].x+v.x;
            pp.y=ans[x].y+v.y;
            ans[to]=pp;
            p[to]=pp-ans[x];
            dfs1(to,x);
            v=Rotate(v,th*siz[to]);
        }
    }
    void solve()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            vec[a].pb(b);
            vec[b].pb(a);
        }
        dfs(1,-1);
        th=pi/n;
        int si=vec[1].size();
        ans[1].x=ans[1].y=0;
        Vector v;
        point pp;
        v.x=1,v.y=0;
        for(int i=0;i<si;i++)
        {
            int to=vec[1][i];
            pp.x=v.x;pp.y=v.y;
            ans[to]=pp;
            p[to]=pp;
            dfs1(to,1);
            v=Rotate(v,th*siz[to]);
        }
        for(int i=1;i<=n;i++)printf("%.10f %.10f
    ",ans[i].x,ans[i].y);
    }
    int main()
    {
        int _=1;
    //    scanf("%d",&_);
        while(_--)solve();
        return 0;
    }
    欢迎加我qq1165750856一起玩呀~
  • 相关阅读:
    【Android】详解Android 网络操作
    【Android】详解Android Service
    【Android】Android的进程优先级
    【Windows】Dos中的日期的和时间
    【Android】详解Android Activity
    【Java】java数据库连接中C3P、DBCP、Druid连接池的使用
    【Windows】Windows中解析DOS的DIR命令使用
    【Android】解析Android的路径
    【Windows】Windows中解析DOS的for命令使用
    【Android】Android实现监听返回键,主键(HOME),菜单键
  • 原文地址:https://www.cnblogs.com/HHHEN/p/14116162.html
Copyright © 2020-2023  润新知