zoukankan      html  css  js  c++  java
  • SGU128 Snake

    SGU128,题意是给定N个点,问说能不能形成一个闭环G,要求G经过每个点,且在每个点处都有90度的转角,且不能出现自交。

    没想出来,通过提供的思路,由于每个点处都需要90度的转弯,因此每个点处必然有一条横向以及一条纵向的路径穿过,单从某个x来看,由于上述限制,因此需要有偶数个点两两配对。然后通过搜索判断是否连通,最后再借助树状数组判断是否有自交的情况(”+”这种自交形状)出现。

    PS: 里有个GDB的简单教程。

    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    const int MAXN = 10005;
    
    pair<int, int> points[MAXN];
    vector<int> x_points[2*MAXN], y_points[2*MAXN];
    int x_link[MAXN], y_link[MAXN];
    bool visit[MAXN], towards[2*MAXN];
    
    class BinaryIndexedTree {
    private:
        int *c_, num_;
    public:
        BinaryIndexedTree() : c_(NULL) {}
        BinaryIndexedTree(int num) : num_(num) {
            c_ = new int[num_];
            memset(c_, 0, sizeof(int) * num_);
        }
        ~BinaryIndexedTree() {
            if (c_ != NULL) {
                delete[] c_;
                c_ = NULL;
            }
        }
    private:
        int lowbit(int x) {
            return x & (-x);
        }
    public:
        int Query(int i) {
            int res = 0;
            while (i > 0) {
                res += c_[i];
                i -= this->lowbit(i);
            }
            return res;
        }
        int Query(int left, int right) {
            return this->Query(right) - this->Query(left - 1); 
        }
        void Update(int i, int value) {
            while (i < num_) {
                c_[i] += value;
                i += this->lowbit(i);
            } 
        }
    };
    
    bool x_cmp(int u, int v) {
        return points[u].first < points[v].first;
    }
    
    bool y_cmp(int u, int v) {
        return points[u].second < points[v].second;
    }
    
    int main()
    {
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; i++) {
            int a, b;
            scanf("%d%d", &a, &b);
            a += 10001;
            b += 10001;
    
            points[i].first = a;
            points[i].second = b;
    
            x_points[a].push_back(i);
            y_points[b].push_back(i);
        }
    
        bool ok = true;
        int total_length = 0;
        memset(x_link, -1, sizeof(x_link));
        memset(y_link, -1, sizeof(y_link));
    
        do {
            // x order 
            for (int i = 0; i < 2 * MAXN; i++) {
                if (x_points[i].size() > 0) {
                    if (x_points[i].size() & 1) {
                        ok = false;
                        break;
                    }
                   
                    sort(x_points[i].begin(), x_points[i].end(), y_cmp);
                    
                    for (int j = 0; j < x_points[i].size(); j += 2) {
                        int down = x_points[i][j];
                        int up = x_points[i][j + 1];
    
                        total_length += (points[up].second - points[down].second);
    
                        y_link[down] = up; y_link[up] = down;
                    }
                }
            }        
            if (!ok)  break;
    
            // y order
            for (int i = 0; i < 2 * MAXN; i++) {
                if (y_points[i].size() > 0) {
                    if (y_points[i].size() & 1) {
                        ok = false;
                        break;
                    }
                   
                    sort(y_points[i].begin(), y_points[i].end(), x_cmp);
                    
                    for (int j = 0; j < y_points[i].size(); j += 2) {
                        int left = y_points[i][j];
                        int right = y_points[i][j + 1];
    
                        total_length += (points[right].first - points[left].first);
    
                        x_link[left] = right; x_link[right] = left;
                    }
                }
            }        
            if (!ok)  break;
    
            // search
            memset(visit, false, sizeof(visit));
            vector<int> Q;
            Q.push_back(0);
            visit[0] = true;
    
            for (int i = 0; i < Q.size(); i++) {
                if (x_link[Q[i]] == -1 || y_link[Q[i]] == -1) {
                    ok = false;
                    break;
                } else {
                    if (visit[x_link[Q[i]]] == false) {
                        visit[x_link[Q[i]]] = true;
                        Q.push_back(x_link[Q[i]]);
                    } 
    
                    if (visit[y_link[Q[i]]] == false) {
                        visit[y_link[Q[i]]] = true;
                        Q.push_back(y_link[Q[i]]);
                    }
                }
            }
    
            for (int i = 0; i < n; i++) {
                if (visit[i] == false) {
                    ok = false;
                    break;
                }
            }
    
            // check self-cross
            memset(towards, false, sizeof(towards));
            BinaryIndexedTree tree = BinaryIndexedTree(MAXN * 2);
            for (int i = 0; i < 2*MAXN; i++) if (x_points[i].size() > 0) {
                for (int j = 0; j < x_points[i].size(); j += 2) {
                    int down = points[x_points[i][j]].second;
                    int up = points[x_points[i][j + 1]].second;
    
                    towards[down] = !towards[down];
                    towards[up] = !towards[up];
    
                    tree.Update(down, towards[down] ? +1 : -1);
                    tree.Update(up, towards[up] ? +1 : -1);
    
                    if (down + 1 < up - 1 && tree.Query(down + 1, up - 1) > 0) {
                        ok = false;
                        break;
                    }
                } 
    
                if (!ok)  break;
            }
    
        } while(0);
    
        if (ok) {
            printf("%d
    ", total_length);
        } else {
            printf("0
    ");
        }
    }
  • 相关阅读:
    Chaikin Curves in Processing
    finalize()方法什么时候被调用?析构函数(finalization)的目的是什么?
    System.gc()和Runtime.gc()的区别?
    GC原理---对象可达判断
    java十题
    在 Queue 中 poll()和 remove()有什么区别?
    ArrayList和LinkedList的区别
    HashSet的实现原理
    Java中HashMap和TreeMap的区别
    List、Map、Set之间的联系与区别:
  • 原文地址:https://www.cnblogs.com/litstrong/p/3252103.html
Copyright © 2011-2022 走看看