分析:行和列无关,分别在行列中排列1-n,要求是第I个整数在[a1,a2]区间里。所以优先按照右边界排列,其次是左边界,这样的话,再依次给每一行或每一列安排位置。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
struct point
{
int pos,a1,a2,ans;//顺序,左边界,右边界,排列后的位置
};
point x[5005],y[5005];
bool vis[5005];
bool cmp(point p1,point p2)
{
if(p1.a2==p2.a2)return p1.a1<p2.a1;
return p1.a2<p2.a2;
}
bool cmp2(point p1,point p2)
{
return p1.pos<p2.pos;
}
int main()
{
int n,x1,x2,y1,y2;
while(scanf("%d",&n)&&n){
for(int i=0;i<n;i++){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x[i].a1=x1;
x[i].a2=x2;
x[i].pos=i;
y[i].a1=y1;
y[i].a2=y2;
y[i].pos=i;
}
sort(x,x+n,cmp);
sort(y,y+n,cmp);
memset(vis,0,sizeof(vis));
bool v=false;
for(int i=0;i<n;i++){
bool flag=false;
for(int j=x[i].a1;j<=x[i].a2;j++){
if(!vis[j]){
x[i].ans=j;
vis[j]=true;
flag=true;
break;
}
}
if(!flag){
v=true;
break;
}
}
if(v){
printf("IMPOSSIBLE\n");
continue;
}
memset(vis,0,sizeof(vis));
v=false;
for(int i=0;i<n;i++){
bool flag=false;
for(int j=y[i].a1;j<=y[i].a2;j++){
if(!vis[j]){
y[i].ans=j;
vis[j]=true;
flag=true;
break;
}
}
if(!flag){
v=true;
break;
}
}
if(v){
printf("IMPOSSIBLE\n");
continue;
}
sort(x,x+n,cmp2);
sort(y,y+n,cmp2);
for(int i=0;i<n;i++){
printf("%d %d\n",x[i].ans,y[i].ans);
}
}
}