标签:
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; }
标签:
原文地址:http://www.cnblogs.com/Emerald/p/4781599.html