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;
    }
    

      

  • 相关阅读:
    Servlet再度学习
    JSP九大内置对象
    Java I/O学习
    Java内存管理
    数据库面试常问的一些基本概念
    JVM类加载原理学习笔记
    Ajax原理学习
    Java基础之泛型
    Java基础之集合
    java多线程快速入门(二)
  • 原文地址:https://www.cnblogs.com/Emerald/p/4781599.html
Copyright © 2011-2022 走看看