题目链接:Fabled Rooks
终于给我过了,这道题目拿到手就相当然的以为是八皇后问题=_=。然后深搜上去,果断超时了。确实,5000的数据规模,深搜的时间复杂度最大O(n3),确实欠考虑。
解题关键:
贪心,注意到x和y的坐标是相互独立的,可以为每个点先分配x点坐标,再分配y点坐标。对于每个点的x(y)坐标,按照L的大小来从小到大排序,L相等的,比较R的大 小。优先级队列里这样维护每个点的x坐标。还要维护一个maxx来表示已经分配到哪个位置。
每次从优先级队列中取最小的节点temp:
若 temp.r<maxx,没法分配,返回false;
若 temp.l<maxx , temp.l=maxx,temp放回队列,重新选取最小的节点;
import java.io.*;
import java.util.*;
class Rook implements Comparable<Rook>{
int l,r,order;
public Rook(int l,int r,int order)
{
this.l=l;
this.r=r;
this.order=order;
}
public int compareTo(Rook o)
{
if(this.l!=o.l)
return this.l>o.l?1:-1;
return this.r>o.r?1:-1;
}
}
public class Main{
static Rook[] areax=null;
static Rook[] areay=null;
static int[][] ans=null;
static int max(int a,int b)
{
return a>=b?a:b;
}
static boolean check(Rook[] areai,int pos)
{
PriorityQueue<Rook> prique=new PriorityQueue<Rook>();
for(int i=0;i<areai.length;i++)
prique.add(areai[i]);
int maxx=0;
while(!prique.isEmpty())
{
Rook temp=prique.poll();
if(temp.r<maxx) return false;
if(temp.l<maxx)
{
temp.l=maxx;
prique.add(temp);
continue;
}
int cur=max(temp.l,maxx);
ans[temp.order][pos]=cur;
maxx=cur+1;
}
return true;
}
public static void main(String[] args)
{
Scanner in=new Scanner(System.in);
int n;
while(in.hasNext())
{
n=in.nextInt();
if(n==0) break;
areax=new Rook[n];
areay=new Rook[n];
ans=new int[n][2];
for(int i=0;i<n;i++)
{
int xl=in.nextInt();
int yl=in.nextInt();
int xr=in.nextInt();
int yr=in.nextInt();
areax[i]=new Rook(xl,xr,i);
areay[i]=new Rook(yl,yr,i);
}
if(check(areax,0)&&check(areay,1))
{
for(int i=0;i<n;i++)
System.out.println(ans[i][0]+" "+ans[i][1]);
}
else
System.out.println("IMPOSSIBLE");
}
}
}