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

 

  

 

posted @ 2015-09-04 13:02  Emerald  阅读(310)  评论(0编辑  收藏  举报