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一起玩呀~
原文地址:https://www.cnblogs.com/HHHEN/p/14116162.html