x轴,y轴不相关,所以分开考虑
贪心法 可以这样思考,不同于定区间选点,而是定点选区间,所以理所当然,要选占用1~col最多位置的区间(因为该地方已经放置好),且尽可能保留占用col+1~n的位置区间为以后考虑;
那么我们要从col=1~n放,对于每个col选取[a,b]中 1) a最小 2)a相同时b最小的区间; 每选中一个区间就把他抹掉;
为什么那么选的原因:
1) a最小 : 因为col是从1到n选的 每次当然要利用a最小的区间,反正<col的位置的root都放好了,越晚选越吃亏
2)a相同时b最小的区间 :让col+1~n的空位越多越好,先把短的区间用掉喽别浪费资源;
代码如下:
#include<iostream> #include<vector> #include<queue> #include<numeric> #include<algorithm> #include<cstdio> #include<cstring> #include<ctime> using namespace std; const int maxn=5000+5; int n,x1[maxn],x2[maxn],y1[maxn],y2[maxn],x[maxn],y[maxn]; bool solve(int* a,int *b,int* c) //[a,b] { memset(c,-1,sizeof(int)*n); // a[i] <= col <= b[i] /*fill(c,c+n,-1) 是对每一个int大小内存块初始化,而memset是对每个字节*/ for(int col=1;col<=n;col++) //在1~n给每个区间放个root { int root=-1,minb=n+1; for(int i=0;i<n;i++) if(c[i]<0&&a[i]<=col&& b[i]<minb) root=i,minb=b[i]; //if(第i个区间未放过&&在左区间a小于要放的位置col&&还有更小的b) if(root<0||minb<col) return false; //if(放不了了||col为要放的位置>b即col在区间[a,b]外) c[root]=col; } return true; } int main() { while(scanf("%d",&n)==1&&n) { for(int i=0;i<n;i++) scanf("%d%d%d%d",&x1[i],&y1[i],&x2[i],&y2[i]); if(solve(x1,x2,x)&&solve(y1,y2,y)) for(int i=0;i<n;i++) printf("%d %d\n",x[i],y[i]); else printf("IMPOSSIBLE\n"); } }