网易历届笔试题(8)

题目描述

又到了周末,小易的房间乱得一团糟。 

他希望将地上的杂物稍微整理下,使每团杂物看起来都紧凑一些,没有那么乱。 

地上一共有n团杂物,每团杂物都包含4个物品。第i物品的坐标用(ai,bi)表示,小易每次都可以将它绕着(xi,yi)逆时针旋转90∘90∘,这将消耗他的一次移动次数。如果一团杂物的4个点构成了一个面积不为0的正方形,我们说它是紧凑的。 

因为小易很懒,所以他希望你帮助他计算一下每团杂物最少需要多少步移动能使它变得紧凑。 

输入描述:

第一行一个数n(1 <= n <= 100),表示杂物的团数。
接下来4n行,每4行表示一团杂物,每行4个数ai, bi,xi, yi, (-104 <= xi, yi, ai, bi <= 104),表示第i个物品旋转的它本身的坐标和中心点坐标。

输出描述:

n行,每行1个数,表示最少移动次数。

示例1

输入

4
1 1 0 0
-1 1 0 0
-1 1 0 0
1 -1 0 0
1 1 0 0
-2 1 0 0
-1 1 0 0
1 -1 0 0
1 1 0 0
-1 1 0 0
-1 1 0 0
-1 1 0 0
2 2 0 1
-1 0 0 -2
3 0 0 -2
-1 1 -2 0

输出

1
-1
3
3

说明

对于第一团杂物,我们可以旋转第二个或者第三个物品1次。

思路:简单的计算几何,考察了一定的编程能力,本题有两个难点:

1⃣️一个点逆时针旋转后的点的坐标如何求

2⃣️根据四个点判断是否为三角形

这两个难点的解决方案可以参考:题解

import java.util.*;
public class Main{
    class Point implements Comparable<Point>{
        int x,y,a,b;
        public Point(int x,int y,int a,int b){
            this.x=x;
            this.y=y;
            this.a=a;
            this.b=b;
        }
        @Override
        public int compareTo(Point p2){
            if(x==p2.x)
                return y>p2.y?1:-1;
            return x>p2.x?1:-1;
        }
    }
    public static void main(String[] args){
        Main God=new Main();
        int total;    
        Scanner in=new Scanner(System.in);
        total=in.nextInt();
        Point[] points=new Point[4];
        for(int i=0;i<total;i++){
            for(int j=0;j<4;j++){
                points[j]=God.new Point(0,0,0,0);
                points[j].x=in.nextInt();
                points[j].y=in.nextInt();
                points[j].a=in.nextInt();
                points[j].b=in.nextInt();
            }
            int count=Integer.MAX_VALUE;
            for(int m=0;m<4;m++)
                for(int n=0;n<4;n++)
                    for(int p=0;p<4;p++)
                        for(int q=0;q<4;q++){
                            if(God.isSquare(God.rotate(points[0],m),God.rotate(points[1],n),
                                       God.rotate(points[2],p),God.rotate(points[3],q)))
                                count=Math.min(count,m+n+p+q);
                        }
            if(count==Integer.MAX_VALUE)
                System.out.println(-1);
            else
                System.out.println(count);
        }
    }
    private boolean isSquare(Point p1,Point p2,Point p3,Point p4){
        Point[] p=new Point[4];
        p[0]=p1;
        p[1]=p2;
        p[2]=p3;
        p[3]=p4;
        Arrays.sort(p);
        int d1=this.dis(p[0],p[1]);
        int d2=this.dis(p[0],p[2]);
        int d3=this.dis(p[1],p[3]);
        int d4=this.dis(p[2],p[3]);
        if(d1==d2 && d2==d3 && d3==d4 && d1!=0 && this.isRightAngle(p[0],p[1],p[2]))
            return true;
        return false;
    }
    private int dis(Point a,Point b){
        return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    }
    private boolean isRightAngle(Point a,Point b,Point c){
        int x=(a.x-b.x)*(a.x-c.x)+(a.y-b.y)*(a.y-c.y);
        return x==0;
    }
    private Point rotate(Point p,int times){
        int x=p.x,y=p.y,a=p.a,b=p.b;
        int xx,yy;
        for(int i=0;i<times;i++){
            xx=a-y+b;
            yy=x-a+b;
            x=xx;
            y=yy;
        }
        return new Point(x,y,a,b);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值