1 /*uva11134
2 在N*N(1<=N<=5000)的棋盘上放置N个车,使它们相互不攻击。
3 1、首先横和竖是可以分开讨论的
4 2、例如行:
5 问题划归成:
6 一条数轴上,将一些限定区间的点放上去,是否能全覆盖?
7 贪心策略:对于包含位置pos的区间,总是把右断点靠左的点放上去。
8 一旦不能放置了,就说明false
9 实现:优先队列+扫一遍
10
11 */
12 #include <iostream>
13 #include <cmath>
14 #include <algorithm>
15 #include <string.h>
16 #include <stdio.h>
17 #include <set>
18 #include <stack>
19 #include <queue>
20 #include <vector>
21 #define maxn 5010
22 using namespace std;
23
24 int N;
25 struct L1{
26 int l,r,k;
27 bool operator<(const L1 & X)const{
28 if (l==X.l) return r<X.r;else return l<X.l;
29 }
30 }Line1[maxn];
31 struct L2{
32 int l,r,k;
33 bool operator<(const L2 & X)const{
34 if (r==X.r) return l>X.l;else return r>X.r;
35 }
36 };
37 int posX[maxn*2],posY[maxn*2],pos[maxn*2];
38 int xl[maxn],yl[maxn],xr[maxn],yr[maxn];
39 void read(){
40 for(int i=1;i<=N;i++){
41 scanf("%d%d%d%d",&xl[i],&yl[i],&xr[i],&yr[i]);
42 }
43 }
44 bool solve(int *l ,int *r ,int *p){
45 //处理行
46 memset(p,-1,sizeof(p));
47 priority_queue<L2>Q1;
48 for(int i=1;i<=N;i++){
49 Line1[i-1]=(L1){l[i],r[i],i};
50 }
51 sort(Line1,Line1+N);
52 int pos=0,cnt=0;
53 for(int i=1;i<=N;i++){
54 while(Line1[pos].l==i && pos<N){
55 L1 nl=Line1[pos];
56 Q1.push((L2){nl.l,nl.r,nl.k});
57 pos++;
58 }
59 if (Q1.empty()) return false;
60 L2 nl=Q1.top();
61 Q1.pop();
62 if (nl.r>=i) p[nl.k]=i;else return false;
63 }
64 // for(int i=1;i<=N;i++) if (p[i]==-1) return false;
65 return true;
66 //处理列
67 }
68 int main(){
69 while(cin>>N && N){
70 read();
71 if (solve(xl,xr,posX) && solve(yl,yr,posY)){
72 for(int i=1;i<=N;i++){
73 printf("%d %d\n",posX[i],posY[i]);
74 }
75 }else printf("IMPOSSIBLE\n");
76 // check();
77 }
78 return 0;
79 }