liuweimingcprogram

E. Dasha and Puzzle 数学题

http://codeforces.com/contest/761/problem/E

给出一颗树,要求在坐标系中用平行于坐标轴的线描绘出来。

要求边不能相交,而且点的坐标唯一。

注意到2^1 + 2^2 + ..... + 2^n = 2^(n + 1) - 1

那就是说,如果第一条边的边长是2^(n + 1),那么后面的边选2^n 、 2^(n -  1)等等,相加起来也不会越过第一条,所以也就不会相交。

 

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 30 + 20;
struct node {
    int u, v, tonext;
} e[maxn * 2];
int num;
int first[maxn];
void add(int u, int v) {
    ++num;
    e[num].u = u;
    e[num].v = v;
    e[num].tonext = first[u];
    first[u] = num;
}
struct coor {
    LL x, y;
    coor(LL xx, LL yy) : x(xx), y(yy) {}
    bool operator < (const struct coor & rhs) const {
        if (x != rhs.x) return x < rhs.x;
        else return y < rhs.y;
    }
};
vector<struct coor>ans[maxn];
int tonext[4][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}};
bool vis[maxn];
const LL one = 1;
int haha[4];
void dfs(int cur, LL x, LL y, int son, int pre) {
    ans[cur].push_back(coor(x, y));
//    aler.insert(coor(x, y));
    vis[cur] = true;
    int to = 0;
    for (int i = first[cur]; i; i = e[i].tonext) {
        int v = e[i].v;
        if (vis[v]) continue;
        if (to == pre) to++;
        if (to == 4) to = 0;
        dfs(v, x + tonext[to][0] * (one << son), y + tonext[to][1] * (one << son), son - 1, haha[to]);
        to++;
    }
}
void work() {
    haha[0] = 2;
    haha[1] = 3;
    haha[2] = 0;
    haha[3] = 1;
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n - 1; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        add(u, v);
        add(v, u);
    }
    for (int i = 1; i <= n; ++i) {
        int t = -1;
        for (int j = first[i]; j; j = e[j].tonext) {
            t++;
        }
        if (t >= 4) {
//            cout << t << endl;
            cout << "NO" << endl;
            return;
        }
    }
//    LL y = 1 << 30;
//    y <<= 2;
//    cout << y << endl;
    dfs(1, 1, 1, 32, -1);
    cout << "YES" << endl;
    for (int i = 1; i <= n; ++i) {
//        if (ans[i].size() == 0) {
//            cout << i << "ffff" << endl;
//            continue;
//        }
        cout << ans[i][0].x << " " << ans[i][0].y << endl;
    }
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}
View Code

 

分类:

技术点:

相关文章: