SW练习_POJ2398_点线关系

这个题目啊,本来是典型的点线关系判断(数量比较小,不用二分查找也能AC)。

但是POJ硬生生的给你整了一个幺蛾子。

输出非让你输出排序后的个数(都怪我看不懂题目,硬生生耗费了2个多小时,题上的用例都过不了)

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.StringTokenizer;
//玩具存储
//解题思路
//将隔板排序一下,如果点不在第一个板左边,那就继续判断第二个边,直到头
//排序的时候,如果板不会交叉,所以按照x或者y排序就行
public class Main{
    static Edge2398[] edges;
    static Res [] res;
    static int[] r;
    public static void main(String[] args) throws Exception{

        /*Node2398 A=new Node2398(100,0);
        Node2398 B=new Node2398(100,10);
        Node2398 C=new Node2398(85,10);

        Node2398 D=new Node2398(100,0);
        Node2398 E=new Node2398(110,10);
        Node2398 F=new Node2398(105,10);
        System.out.println(clock_direction(A,B,C));
        System.out.println(clock_direction(D,E,F));

        return ;*/

        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
        while(true){
            StringTokenizer st=new StringTokenizer(reader.readLine());//The first line consists of six integers n, m, x1, y1, x2, y2
            int N=Integer.parseInt(st.nextToken());//纸板的数量
            if(N==0){
                break;
            }
            edges=new Edge2398[N+1];
            res=new Res[N+1];
            r=new int[N+1];
            for (int i = 0; i <res.length ; i++) {
                res[i]=new Res(i,0);
            }
            int M=Integer.parseInt(st.nextToken());//玩具的数量
            int x1=Integer.parseInt(st.nextToken());//左上角的坐标
            int y1=Integer.parseInt(st.nextToken());
            int x2=Integer.parseInt(st.nextToken());//右下角的坐标
            int y2=Integer.parseInt(st.nextToken());
            for (int i = 0; i <N ; i++) {//处理N个纸板
                st=new StringTokenizer(reader.readLine());//Ui Li
                int Ui=Integer.parseInt(st.nextToken());//(Ui, y1) and (Li, y2)
                int Li=Integer.parseInt(st.nextToken());
                edges[i]=new Edge2398(Li,y2,Ui,y1);
            }
            edges[N]=new Edge2398(x2,y2,x2,y1);
            Arrays.sort(edges);
            for (int i = 0; i <M ; i++) {//处理M个玩具
                st=new StringTokenizer(reader.readLine());//接收玩具的坐标
                int xx=Integer.parseInt(st.nextToken());
                int yy=Integer.parseInt(st.nextToken());
                Node2398 node=new Node2398(xx,yy);
                //System.out.println("edges.length:"+edges.length);
                //System.out.println(node);
                for (int j=0;j<edges.length;j++) {
                    Edge2398 e=edges[j];
                    //System.out.println(e);
                    if(leftCheck(e,node)){//在这个板子的左边,不用再继续了
                        res[j].cout++;
                        //System.out.printf("点 %d,%d 在 %d 个板的左侧(%d,%d,%d,%d) \n",node.x,node.y,j,e.sx,e.sy,e.ex,e.ey);
                        break;
                    }else{
                        //System.out.printf("点 %d,%d 在 %d 个板的右侧(%d,%d,%d,%d) \n",node.x,node.y,j,e.sx,e.sy,e.ex,e.ey);
                    }
                }
            }
            //System.out.println(Arrays.toString(res));
            for (int i = 0; i <res.length ; i++) {
                if(res[i].cout!=0){
                    //System.out.println(res[i].cout);
                    r[res[i].cout]++;
                }
            }
            System.out.println("Box");
            for (int i = 0; i < r.length; i++) {
                if(r[i]!=0){
                    System.out.println(i+": "+r[i]);
                }
            }
        }

        reader.close();
    }

    public static boolean leftCheck(Edge2398 edge,Node2398 C){
        Node2398 A=new Node2398(edge.sx,edge.sy);
        Node2398 B=new Node2398(edge.ex,edge.ey);
        return !clock_direction(A,B,C);

    }

    public static boolean clock_direction(Node2398 A,Node2398 B,Node2398 C) {
        int dxAB = B.x - A.x;
        int dyAB = B.y - A.y;
        int dxAC = C.x - A.x;
        int dyAC = C.y - A.y;
        boolean flag=false;
        //int abc = BigInteger.valueOf(dxAB).multiply(BigInteger.valueOf(dyAC)).compareTo(
        //        BigInteger.valueOf(dyAB).multiply(BigInteger.valueOf(dxAC))
        //);
        int abc=dxAB*dyAC-dyAB*dxAC;
        //System.out.println(abc);
        //int abc=(A.y*B.x+B.y*C.x+C.y*A.x)-(A.x*B.y+B.x*C.y+C.x*A.y);
        if (abc > 0) {
            flag= false;//逆时针
        } else if (abc < 0) {
            flag= true;//顺时针
        }
        return flag;
    }


}
class Res implements Comparable<Res>{
    int index;
    int cout;
    public Res(int index, int cout) {
        this.index = index;
        this.cout = cout;
    }

    @Override
    public int compareTo(Res o) {
        return o.cout-this.cout!=0?o.cout-this.cout:this.index-o.index;
    }

    @Override
    public String toString() {
        return "Res{" +
                "index=" + index +
                ", cout=" + cout +
                '}';
    }
}
class Node2398{
    int x;
    int y;
    public Node2398(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "Node2398{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }
}
class Edge2398 implements Comparable<Edge2398>{
    int sx;
    int sy;
    int ex;
    int ey;
    public Edge2398(int sx, int sy, int ex, int ey) {
        this.sx = sx;
        this.sy = sy;
        this.ex = ex;
        this.ey = ey;
    }

    @Override
    public int compareTo(Edge2398 o) {
        return this.sx-o.sx;
    }

    @Override
    public String toString() {
        return "Edge2398{" +
                "sx=" + sx +
                ", sy=" + sy +
                ", ex=" + ex +
                ", ey=" + ey +
                '}';
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值