标签:style lse pos 范围 线段 ret 端点 使用 c++
首先,根据数据范围,可以得到这是一题O(N2)
考虑贪心
发现行和列是不相关的,于是可以把他们分成两个一维区间问题,也就是在线段中选出点使得每个线段中都有一个点,求出方案。
先考虑尽量不对后面造成影响,也就是留后路,所以前面要尽量选靠前的,按照右端点排序,分别处理。
最后记得按原序号输出。
#include<bits/stdc++.h> using namespace std; int n; bool b1[5005],b2[5005]; struct node{int x1,x2,y1,y2,x,y,ind;}a[5005]; bool cmp(node a,node b){return a.x2<b.x2;}//第一次排序 bool cmp1(node a,node b){return a.y2<b.y2;}//第二次 bool cmp2(node a,node b){return a.ind<b.ind;}//第三次 bool ccf(){//咳咳 fill(b1,b1+n+1,0);fill(b2,b2+n+1,0);//清零使用数组 for(int i=1;i<=n;i++){ scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);//输入 a[i].ind=i;记录序号 } sort(a+1,a+n+1,cmp);//处理横坐标 for(int i=1;i<=n;i++){ int j=a[i].x1; for(;j<=a[i].x2;++j)//从前往后找 if(!b1[j]){b1[j]=1,a[i].x=j;break;} if(j>a[i].x2)return false;//如果找不到就返回 } sort(a+1,a+n+1,cmp1);//处理纵坐标 for(int i=1;i<=n;i++){ int j=a[i].y1; for(;j<=a[i].y2;++j) if(!b2[j]){b2[j]=1,a[i].y=j;break;} if(j>a[i].y2)return false; } sort(a+1,a+n+1,cmp2);//按照原序号输出 for(int i=1;i<=n;i++) printf("%d %d\n",a[i].x,a[i].y); return true; } int main(){ while(~scanf("%d",&n)&&n) if(!ccf())puts("IMPOSSIBLE"); }
标签:style lse pos 范围 线段 ret 端点 使用 c++
原文地址:https://www.cnblogs.com/coder-cjh/p/11617059.html