题目大意:将各个元件按照某个次序向y轴负半轴移动,直到所有元件全部移出工作区,我的想法是如果a元件的左端点横坐标在b元件两个端点的横坐标中间时,判断a元件左端点的纵坐标ya与a元件左端点横坐标在b元件上的纵坐标位置yb,如果ya大于yb,说明要先移动b元件,所以我们可以建图点b指向a,a点的入度增加,n^2遍历所有的元件之后可以得到一个图,然后进行拓扑排序输出即可。
ac代码:
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static class edge {
int x1,y1,x2,y2;
edge(int a,int b,int c,int d){
x1=a;
y1=b;
x2=c;
y2=d;
}
}
static class bian{//用来存边的邻接表
int v,next;
bian(int v,int next){
this.v=v;
this.next=next;
}
}
static int p[]=new int[6005];
static bian b[]=new bian[5000000];//刚开始开200万发现不够
static int eid=0;
static void insert(int u,int v){
b[eid]=new bian(v,p[u]);
p[u]=eid++;
}
static edge e[]=new edge[6005];
static int rudu[]=new int[6005];//存储元件的入度
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Arrays.fill(p, -1);
for(int i=1;i<=n;i++){
int a=sc.nextInt();
int b=sc.nextInt();
int c=sc.nextInt();
int d=sc.nextInt();
if(a>c){
int temp=a;
a=c;
c=temp;
temp=b;
b=d;
d=temp;
}
e[i]=new edge(a,b,c,d);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i!=j&&e[i].x1>=e[j].x1&&e[i].x1<=e[j].x2){
double y;
if(e[j].x1==e[j].x2)
y=(e[j].y1+e[j].y2)/2.0;
else
y=1.0*(e[i].x1-e[j].x1)*(e[j].y2-e[j].y1)/(e[j].x2-e[j].x1)+e[j].y1;
if(y>e[i].y1){ //比较两个y的大小来判断优先度
rudu[j]++;
insert(i,j);
}else{
rudu[i]++;
insert(j,i);
}
}
}
}
Queue<Integer> q=new LinkedList<Integer>();
for(int i=1;i<=n;i++) //拓扑排序,初始入度为0的点入队列
if(rudu[i]==0)
q.add(i);
while(!q.isEmpty()){
int u=q.poll();
for(int i=p[u];i!=-1;i=b[i].next){
int v=b[i].v;
if(--rudu[v]==0)
q.add(v);
}
if(!q.isEmpty())
System.out.print(u+" ");
else
System.out.println(u);
}
sc.close();
}
}