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

浙公网安备 33010602011771号