zoukankan      html  css  js  c++  java
  • uva 11134 Fabled Rooks

    Thinking about it:

      题目意思有点类似于八皇后,但没有了斜方向上的限制,而多了一个摆放区域的限制。因为题目中的N最大达5000,不敢贸然采用回溯法。可以得知,题中每个Rook的摆放区域是一个矩形,而且每个在摆放时,x,y轴其实是相互独立的,如何摆放x轴的位置并不影响y轴。因此可以先摆放x轴的位置,再摆放y轴的位置,这样子,题目看上去就像是区间相关的贪心算法题。

      对于x轴的区间,排序,规则:xr小的排前面,若xr相同,则xl小的排前面。每次选择一个区间的x位置时,尽量选小的x。

      对于y轴,也是同样的处理方式。

    Reference:

      1.http://acm.lilingfei.com/uva-11134-fabled-rooks-%E4%BE%8B%E9%A2%988-4_67

      2.《算法竞赛入门经典(第二版)》

    PS:

      刚开始作题时,排序思路错误,结果没有发现,直至参考了别人的思路(Click Here):如果按x尽量小的选,排序必须先按 xr 小的排序!例子就是:

      两个区间a和b的范围分别是 [4,9] 和 [5,8]。按照排序规则,a要排在b上面:

      (a)   4 5 6 7 8 9

      (b)     5 6 7 8

      如果此时 1-7 都已经被其他的车占领,那么a区间会选择占据 8。区间b就会返回无解。但实际上a可以占9,而b占8

     

    Code:

    /**
     * AC @ Sep 4th 2015
     * Run Time : 0.009s
     */
    #include <bits/stdc++.h>
    
    using namespace std;
    
    struct Node {
        int xl, xr, yl, yr;
        int x, y, order;
    };
    
    // global
    const int MAXN = 5000 + 50;
    int N;
    std::vector<Node> v;
    
    bool read() {
        cin >> N;
        if (N == 0) {
            return false;
        }
        v.clear();
        Node t;
        for (int i = 0; i < N; ++i) {
            cin >> t.xl >> t.yl >> t.xr >> t.yr;
            t.order = i;
            v.push_back(t);
        }
        return true;
    }
    
    bool cmp_x(Node &a, Node &b) {
        return a.xr < b.xr || (a.xr == b.xr && a.xl < b.xl);
    }
    // bool cmp_x(Node &a, Node &b) {
    //     return a.xl < b.xl || (a.xl == b.xl && a.xr < b.xr);
    // }
    // this function is wrong used for sorting in this problem
    // cmp the r first, then l
    
    bool cmp_y(Node &a, Node &b) {
        return a.yr < b.yr || (a.yr == b.yr && a.yl < b.yl);
    }
    
    bool cmp_order(Node &a, Node &b) {
        return a.order < b.order;
    }
    
    bool is_possile() {
        bool vis[MAXN] = {false};
        sort(v.begin(), v.end(), cmp_x);
        for (int i = 0; i < N; ++i) {
            int l = v[i].xl, r = v[i].xr;
            while (l <= r && vis[l]) {
                ++l;
            }
            if (l > r) {
                return false;
            }
            vis[l] = true;
            v[i].x = l;
        }
        sort(v.begin(), v.end(), cmp_y);
        memset(vis, false, sizeof(vis));
        for (int i = 0; i < N; ++i) {
            int l = v[i].yl, r = v[i].yr;
            while (l <= r && vis[l]) {
                ++l;
            }
            if (l > r) {
                return false;
            }
            vis[l] = true;
            v[i].y = l;
        }
        return true;
    }
    
    void output() {
        sort(v.begin(), v.end(), cmp_order);
        for (std::vector<Node>::iterator it = v.begin(); it != v.end(); ++it) {
            cout << it->x << " " << it->y << endl;
        }
    }
    
    void work() {
        if(is_possile() == false) {
            cout << "IMPOSSIBLE" << endl;
        } else {
            output();
        }
    }
    
    int main(int argc, char const *argv[]) {
        ios::sync_with_stdio(false);
        cin.tie(0);
        while (read()) {
            work();
        }
        return 0;
    }
    

      

  • 相关阅读:
    LeetCode Array Easy 414. Third Maximum Number
    LeetCode Linked List Medium 2. Add Two Numbers
    LeetCode Array Easy 283. Move Zeroes
    LeetCode Array Easy 268. Missing Number
    LeetCode Array Easy 219. Contains Duplicate II
    LeetCode Array Easy 217. Contains Duplicate
    LeetCode Array Easy 189. Rotate Array
    LeetCode Array Easy169. Majority Element
    LeetCode Array Medium 11. Container With Most Water
    LeetCode Array Easy 167. Two Sum II
  • 原文地址:https://www.cnblogs.com/Emerald/p/4781599.html
Copyright © 2011-2022 走看看