题意:有n个车放到n*n的矩形内,任意两个车不在同一条竖线或横线上,且给出了每辆车在矩形内的范围,问是否有一种方法可以使n个车都有位置摆放,输出所有车的位置,否则输出IMPOSSIBLE。
题解:像n皇后问题,但因为n的范围是5000,所以肯定不能dfs,那就要排序,把所有车先根据x的范围按从小到大排序,然后每行只能摆放一辆,如果做不到就IMPOSSIBLE,然后按y的范围从小到大排序,每列只能摆一辆,做不到就IMPOSSIBLE,如果可以全部摆好就输出坐标。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 5005;
struct Point {
int x1, y1, x2, y2;
int id;
}p[N];
int n, flag, res[N][2], vis[N];
int cmpx(Point a, Point b) {
if (a.x2 == b.x2)
return a.x1 < b.x1;
return a.x2 < b.x2;
}
int cmpy(Point a, Point b) {
if (a.y2 == b.y2)
return a.y1 < b.y1;
return a.y2 < b.y2;
}
bool solve() {
sort(p, p + n, cmpx);
memset(vis, 0, sizeof(vis));
for (int i = 0; i < n; i++) {
flag = 0;
for (int x = p[i].x1; x <= p[i].x2; x++)
if (!vis[x]) {
flag = 1;
res[p[i].id][0] = x;
vis[x] = 1;
break;
}
if (!flag)
return false;
}
sort(p, p + n, cmpy);
memset(vis, 0, sizeof(vis));
for (int i = 0; i < n; i++) {
flag = 0;
for (int y = p[i].y1; y <= p[i].y2; y++)
if (!vis[y]) {
flag = 1;
res[p[i].id][1] = y;
vis[y] = 1;
break;
}
if (!flag)
return false;
}
for (int i = 0; i < n; i++)
printf("%d %d\n", res[i][0], res[i][1]);
return true;
}
int main() {
while (scanf("%d", &n) && n) {
for (int i = 0; i < n; i++) {
scanf("%d%d%d%d", &p[i].x1, &p[i].y1, &p[i].x2, &p[i].y2);
p[i].id = i;
}
if (!solve())
printf("IMPOSSIBLE\n");
}
return 0;
}