# PTA博客作业(二)

PTA博客作业(二)

1.前言

 在本次PTA题目集4(四边形)、题目集5(五边形)以及最后的期中考试里,题目集4难度适中,题目集5难度最大,期中考试难度最小。其中题目集4是上次作业题目集3的延伸,另外有两题测试了正则表达式的运用,题目集5是点线面到多边形的整合,需要考虑很多种情况,而期中考试则是对类的基础知识点的复习,较为简单。

2.设计与分析

①题集四

7-2 点线形系列4-凸四边形的计算

题目:
用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。
2:输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
3:输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
4:输入六个点坐标,前两个点构成一条直线,后四个点构成一个四边形或三角形,输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积(不换行)。若直线与四边形或三角形的一条边线重合,输出"The line is coincide with one of the lines"。若后四个点不符合四边形或三角形的输入,输出"not a quadrilateral or triangle"。
后四个点构成三角形的情况:假设三角形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z 不与xy都相邻,如z x y s、x z s y、x s z y
5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部(若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。如果点在多边形的某条边上,输出"on the triangle或者on the quadrilateral"。若后四个点不符合四边形或三角形,输出"not a quadrilateral or triangle"。

输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。

输出格式:
基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0

选项1、2、3中,若四边形四个点中有重合点,输出"points coincide"。
选项4中,若前两个输入线的点重合,输出"points coincide"。

题目分析:
本题是上次题目集的延伸,由三角形延伸到了四边形,同时需要考虑到点的输出顺序,若点的输出顺序错误,则无法构成四边形,此为本题一大难点,可以从对角线交点位置入手。此外关于凹凸四边形,可以考虑分割并比较面积来判断。最后则是分割,在三角形分割的基础上,判断切割的多边形是三角形或者是多边形,根据情况进行面积计算。

源码展示:

import java.util.Scanner;
import java.text.DecimalFormat;
public class Main
{
    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);
        String s= input.nextLine();
        Judge.cheek(s);
        Point point=new Point();
        Line line=new Line();
        Triangle triangle=new Triangle();
        Quadrilateral quadrilateral=new Quadrilateral();
        double[][] points= point.getpoint(s);
        if(Judge.choice(s)=='1')
        {
            Judge.coincide(points,Judge.choice(s));
            if(quadrilateral.judge(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1]))
                System.out.print("true ");
            else
                System.out.print("false ");
            if(quadrilateral.parallelogram(points)&&quadrilateral.judge(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1]))
                System.out.print("true");
            else
                System.out.print("false");
        }
        else if(Judge.choice(s)=='2')
        {
            if(!quadrilateral.judge(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1]))
            {
                System.out.print("not a quadrilateral");
                System.exit(0);
            }
            Judge.coincide(points,Judge.choice(s));
            if(quadrilateral.diamond(points))
                System.out.print("true ");
            else
                System.out.print("false ");
            if(quadrilateral.rectangle(points))
                System.out.print("true ");
            else
                System.out.print("false ");
            if(quadrilateral.square(points))
                System.out.print("true");
            else
                System.out.print("false");
        }
        else if(Judge.choice(s)=='3')
        {
            if(!quadrilateral.judge(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1]))
            {
                System.out.print("not a quadrilateral");
                System.exit(0);
            }
            Judge.coincide(points,Judge.choice(s));
            if(quadrilateral.aotu(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1])!=0)
            {
                System.out.print("false "+Judge.change(quadrilateral.girth(points))+" "+Judge.change(quadrilateral.area(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1])));
            }
            else
            {
                System.out.print("true "+Judge.change(quadrilateral.girth(points))+" "+Judge.change(quadrilateral.area(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1])));
            }
        }
        else if(Judge.choice(s)=='4')
        {
            if(points[0][0]==points[1][0]&&points[0][1]==points[1][1])
            {
                System.out.print("points coincide");
                System.exit(0);
            }
            if(triangle.judge(points[2][0],points[2][1],points[3][0],points[3][1],points[4][0],points[4][1],points[5][0],points[5][1])&&!quadrilateral.judge(points[2][0],points[2][1],points[3][0],points[3][1],points[4][0],points[4][1],points[5][0],points[5][1]))
            {
                if(triangle.coincide(points))
                {
                    System.out.print("The line is coincide with one of the lines");
                    System.exit(0);
                }
                else
                    triangle.cut(points);
            }
            else if(!triangle.judge(points[2][0],points[2][1],points[3][0],points[3][1],points[4][0],points[4][1],points[5][0],points[5][1])&&quadrilateral.judge(points[2][0],points[2][1],points[3][0],points[3][1],points[4][0],points[4][1],points[5][0],points[5][1]))
            {
                if(quadrilateral.coincide(points))
                {
                    System.out.print("The line is coincide with one of the lines");
                    System.exit(0);
                }
                else
                    quadrilateral.cut(points);
            }
            else
            {
                System.out.print("not a quadrilateral or triangle");
                System.exit(0);
            }
        }
        else
        {
            if(triangle.judge(points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1],points[4][0],points[4][1]))
            {
                if(line.online(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1],points[4][0],points[4][1]))
                    System.out.print("on the triangle");
                else if(triangle.inorout2(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1],points[4][0],points[4][1]))
                    System.out.print("in the triangle");
                else
                    System.out.print("outof the triangle");
            }
            else if(quadrilateral.judge(points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1],points[4][0],points[4][1]))
            {
                if(line.online(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1],points[4][0],points[4][1]))
                    System.out.print("on the quadrilateral");
                else if(quadrilateral.inorout(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1],points[4][0],points[4][1]))
                    System.out.print("in the quadrilateral");
                else
                    System.out.print("outof the quadrilateral");
            }
            else
                System.out.print("not a quadrilateral or triangle");
        }
    }
}
class Judge
{
    public static void cheek(String str)
    {
        String s2;
        String[] s1, s3, num;
        char a, b;
        a = str.charAt(0);
        b = str.charAt(1);
        if (b != ':')
        {
            System.out.print("Wrong Format");
            System.exit(0);
        }
        else if (a < '1' || a > '5')
        {
            System.out.print("Wrong Format");
            System.exit(0);
        }
        else
        {
            s1 = str.split(":");
            if (s1.length != 2)
            {
                System.out.print("Wrong Format");
                System.exit(0);
            }
            s2 = s1[1];
            s3 = s2.split(" ");
            for (String i : s3)
            {
                num = i.split(",");
                if (num.length != 2)
                {
                    System.out.print("Wrong Format");
                    System.exit(0);
                }
                for (String j : num)
                    if (!j.matches("^[+-]?(0|[1-9][0-9]*(\\.\\d+)?|(0\\.\\d+)?)"))
                    {
                        System.out.print("Wrong Format");
                        System.exit(0);
                    }
            }
            if (s3.length != 4 && (a=='1'|| a == '2' || a == '3'))
            {
                System.out.print("wrong number of points");
                System.exit(0);
            }
            else if (s3.length != 6 && a == '4')
            {
                System.out.print("wrong number of points");
                System.exit(0);
            }
            else if(s3.length != 5 && a == '5')
            {
                System.out.print("wrong number of points");
                System.exit(0);
            }
        }
    }
    public static char choice(String str)
    {
        return str.charAt(0);
    }
    public static void coincide(double[][] points,char a)
    {
        if(a=='1'||a=='2'||a=='3')
        {
            for(int i=0;i<3;i++)
                for (int j=i+1;j<4;j++)
                    if(points[i][0]==points[j][0]&&points[i][1]==points[j][1])
                    {
                        System.out.print("points coincide");
                        System.exit(0);
                    }
        }
        else if(a=='4')
        {
            if(points[0][0]==points[1][0]&&points[0][1]==points[1][1])
            {
                System.out.print("points coincide");
                System.exit(0);
            }
        }
    }
    public static String change(double s)
    {
        int length=0;
        String format = new DecimalFormat("#.###").format(s);
        for(int i=0;i<format.length();i++)
        {
            if(format.charAt(i)=='.')
            {
                length++;
                break;
            }
        }
        if(length!=0)
            return format;
        else
        {
            String num=format+".0";
            return num;
        }
    }
}
class Point
{
    public static double[][] points=new double[6][2];
    public double[][] getpoint(String s)
    {
        String s2;
        String[] s1, s3, num;
        int m,n;
        s1 = s.split(":");
        s2 = s1[1];
        s3 = s2.split(" ");
        m=0;
        for(String i:s3)
        {
            num = i.split(",");
            n=0;
            for (String j : num)
            {
                points[m][n]=Double.parseDouble(j);
                n++;
            }
            m++;
        }
        return points;
    }
    public boolean adjacent(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
    {
        double a1=y3-y1;
        double a2=y4-y2;
        double b1=x1-x3;
        double b2=x2-x4;
        double c1=x3*y1-x1*y3;
        double c2=x4*y2-x2*y4;
        if(a1*b2-a2*b1==0)
            return false;
        double x=(b2*c1-b1*c2)/(a2*b1-a1*b2);
        double y=(a1*c2-a2*c1)/(a2*b1-a1*b2);
        if((x-x1)*(x-x3)<0||(x-x2)*(x-x4)<0||(y-y1)*(y-y3)<0||(y-y2)*(y-y4)<0)
            return true;
        else
            return false;
    }
}
class Line
{
    public double[] cutPoint=new double[4];
    public int k=0;
    public boolean coincide(double x1,double y1,double x2,double y2,double x3,double y3)
    {
        double a=y2-y1;
        double b=x1-x2;
        double c=x2*y1-x1*y2;
        if(a*x3+b*y3+c==0)
            return true;
        return false;
    }
    public boolean parallel(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
    {
        double a1=y2-y1;
        double b1=x1-x2;
        double a2=y4-y3;
        double b2=x3-x4;
        if(a1*b2-a2*b1==0)
            return true;
        return false;
    }
    public double dis1(double x1,double y1,double x2,double y2)
    {
        double dis;
        dis=Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
        return dis;
    }
    public boolean online(double x,double y,double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
    {
        if(coincide(x,y,x1,y1,x2,y2)&&(x-x1)*(x-x2)<=0&&(y-y1)*(y-y2)<=0)
            return true;
        if(coincide(x,y,x1,y1,x3,y3)&&(x-x1)*(x-x3)<=0&&(y-y1)*(y-y3)<=0)
            return true;
        if(coincide(x,y,x1,y1,x4,y4)&&(x-x1)*(x-x4)<=0&&(y-y1)*(y-y4)<=0)
            return true;
        if(coincide(x,y,x2,y2,x3,y3)&&(x-x2)*(x-x3)<=0&&(y-y2)*(y-y3)<=0)
            return true;
        if(coincide(x,y,x2,y2,x4,y4)&&(x-x2)*(x-x4)<=0&&(y-y2)*(y-y4)<=0)
            return true;
        if(coincide(x,y,x3,y3,x4,y4)&&(x-x3)*(x-x4)<=0&&(y-y3)*(y-y4)<=0)
            return true;
        return false;
    }
    public boolean intersect(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
    {
        double x,y;
        double a1=y2-y1;
        double b1=x1-x2;
        double a2=y4-y3;
        double b2=x3-x4;
        double c1=x2*y1-x1*y2;
        double c2=x4*y3-x3*y4;
        if(a1*b2-a2*b1==0)
            return false;
        else
        {
            x=(b2*c1-b1*c2)/(a2*b1-a1*b2);
            y=(a1*c2-a2*c1)/(a2*b1-a1*b2);
            if(((x-x3)*(x-x4)<0||(y-y3)*(y-y4)<0)||(x==x3&&y==y3)||(x==x4&&y==y4))
            {
                if(k==0)
                {
                    this.cutPoint[0]=x;
                    this.cutPoint[1]=y;
                    this.k++;
                }
                else
                {
                    if((this.cutPoint[0]!=x||this.cutPoint[1]!=y)&&k<2)
                    {
                        this.cutPoint[2]=x;
                        this.cutPoint[3]=y;
                        this.k++;
                    }
                }
                return true;
            }
            else
                return false;
        }
    }
}
class Triangle
{
    public double[][] point=new double[3][2];
    Line line=new Line();
    public boolean judge(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
    {
        if(x1==x2&&y1==y2)
        {
            this.point[0][0]=x1;this.point[0][1]=y1;
            this.point[1][0]=x3;this.point[1][1]=y3;
            this.point[2][0]=x4;this.point[2][1]=y4;
            return true;
        }
        if(x1==x3&&y1==y3)
        {
            this.point[0][0]=x1;this.point[0][1]=y1;
            this.point[1][0]=x2;this.point[1][1]=y2;
            this.point[2][0]=x4;this.point[2][1]=y4;
            return true;
        }
        if(x1==x4&&y1==y4)
        {
            this.point[0][0]=x1;this.point[0][1]=y1;
            this.point[1][0]=x2;this.point[1][1]=y2;
            this.point[2][0]=x3;this.point[2][1]=y3;
            return true;
        }
        if(x2==x3&&y2==y3)
        {
            this.point[0][0]=x1;this.point[0][1]=y1;
            this.point[1][0]=x2;this.point[1][1]=y2;
            this.point[2][0]=x4;this.point[2][1]=y4;
            return true;
        }
        if(x2==x4&&y2==y4)
        {
            this.point[0][0]=x1;this.point[0][1]=y1;
            this.point[1][0]=x2;this.point[1][1]=y2;
            this.point[2][0]=x3;this.point[2][1]=y3;
            return true;
        }
        if(x3==x4&&y3==y4)
        {
            this.point[0][0]=x1;this.point[0][1]=y1;
            this.point[1][0]=x2;this.point[1][1]=y2;
            this.point[2][0]=x3;this.point[2][1]=y3;
            return true;
        }
        if(!line.coincide(x1,y1,x3,y3,x4,y4)&&line.coincide(x1,y1,x2,y2,x3,y3)&&(x2-x1)*(x2-x3)<=0&&(y2-y1)*(y2-y3)<=0)
        {
            this.point[0][0]=x1;this.point[0][1]=y1;
            this.point[1][0]=x3;this.point[1][1]=y3;
            this.point[2][0]=x4;this.point[2][1]=y4;
            return true;
        }
        if(!line.coincide(x2,y2,x3,y3,x4,y4)&&line.coincide(x1,y1,x2,y2,x4,y4)&&(x1-x2)*(x1-x4)<=0&&(y1-y2)*(y1-y4)<=0)
        {
            this.point[0][0]=x2;this.point[0][1]=y2;
            this.point[1][0]=x3;this.point[1][1]=y3;
            this.point[2][0]=x4;this.point[2][1]=y4;
            return true;
        }
        if(!line.coincide(x1,y1,x2,y2,x3,y3)&&line.coincide(x1,y1,x3,y3,x4,y4)&&(x4-x1)*(x4-x3)<=0&&(y4-y1)*(y4-y3)<=0)
        {
            this.point[0][0]=x1;this.point[0][1]=y1;
            this.point[1][0]=x2;this.point[1][1]=y2;
            this.point[2][0]=x3;this.point[2][1]=y3;
            return true;
        }
        if(!line.coincide(x1,y1,x2,y2,x4,y4)&&line.coincide(x2,y2,x3,y3,x4,y4)&&(x3-x2)*(x3-x4)<=0&&(y3-y2)*(y3-y4)<=0)
        {
            this.point[0][0]=x1;this.point[0][1]=y1;
            this.point[1][0]=x2;this.point[1][1]=y2;
            this.point[2][0]=x4;this.point[2][1]=y4;
            return true;
        }
        return false;
    }
    public double getarea(double x1,double y1,double x2,double y2,double x3,double y3)
    {
        double l1,l2,l3,p,s;
        l1=Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
        l2=Math.sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));
        l3=Math.sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));
        p=(l1+l2+l3)/2;
        s=Math.sqrt(p*(p-l1)*(p-l2)*(p-l3));
        return s;
    }
    public boolean coincide(double[][] points)
    {
        double a,b,c;
        a=points[1][1]-points[0][1];
        b=points[0][0]-points[1][0];
        c=points[1][0]*points[0][1]-points[0][0]*points[1][1];
        if(a*point[0][0]+b*point[0][1]+c==0&&a*point[1][0]+b*point[1][1]+c==0)
            return true;
        if(a*point[0][0]+b*point[0][1]+c==0&&a*point[2][0]+b*point[2][1]+c==0)
            return true;
        if(a*point[1][0]+b*point[1][1]+c==0&&a*point[2][0]+b*point[2][1]+c==0)
            return true;
        return false;
    }
    public boolean inorout(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
    {
        double ar1,ar2,ar3,ar4;
        ar1=getarea(x1,y1,x2,y2,x3,y3);
        ar2=getarea(x1,y1,x2,y2,x4,y4);
        ar3=getarea(x1,y1,x4,y4,x3,y3);
        ar4=getarea(x4,y4,x2,y2,x3,y3);
        if(Math.abs(ar4-ar3-ar2-ar1)<0.1)
            return true;
        else
            return false;
    }
    public boolean inorout2(double x,double y,double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
    {
        double ar1,ar2,ar3,ar4,ar5,ar6,ar;
        ar1=getarea(x,y,x1,y1,x2,y2);
        ar2=getarea(x,y,x1,y1,x3,y3);
        ar3=getarea(x,y,x1,y1,x4,y4);
        ar4=getarea(x,y,x2,y2,x3,y3);
        ar5=getarea(x,y,x2,y2,x4,y4);
        ar6=getarea(x,y,x3,y3,x4,y4);
        if(line.coincide(x1,y1,x2,y2,x3,y3))
        {
            ar=getarea(x1,y1,x3,y3,x4,y4);
            if(Math.abs(ar-ar2-ar3-ar6)<0.1)
                return true;
        }
        if(line.coincide(x2,y2,x3,y3,x4,y4))
        {
            ar=getarea(x1,y1,x2,y2,x4,y4);
            if(Math.abs(ar-ar1-ar5-ar3)<0.1)
                return true;
        }
        if(line.coincide(x1,y1,x3,y3,x4,y4))
        {
            ar=getarea(x1,y1,x2,y2,x3,y3);
            if(Math.abs(ar-ar1-ar4-ar2)<0.1)
                return true;
        }
        if(line.coincide(x1,y1,x2,y2,x4,y4))
        {
            ar=getarea(x2,y2,x3,y3,x4,y4);
            if(Math.abs(ar-ar4-ar5-ar6)<0.1)
                return true;
        }
        return false;
    }
    public void cut(double[][] points)
    {
        double s,s1=0,s2;
        int flag1=0,flag2=0,flag3=0;
        double a=points[1][1]-points[0][1];
        double b=points[0][0]-points[1][0];
        double c=points[1][0]*points[0][1]-points[0][0]*points[1][1];
        if(line.intersect(points[0][0],points[0][1],points[1][0],points[1][1],point[0][0],point[0][1],point[1][0],point[1][1]))
            flag1=1;
        if(line.intersect(points[0][0],points[0][1],points[1][0],points[1][1],point[0][0],point[0][1],point[2][0],point[2][1]))
            flag2=1;
        if(line.intersect(points[0][0],points[0][1],points[1][0],points[1][1],point[1][0],point[1][1],point[2][0],point[2][1]))
            flag3=1;
        System.out.print(line.k);
        s=getarea(point[0][0],point[0][1],point[1][0],point[1][1],point[2][0],point[2][1]);
        if(line.k==2)
        {
            if(a*point[0][0]+b*point[0][1]+c==0)
                s1=getarea(point[2][0],point[2][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(a*point[1][0]+b*point[1][1]+c==0)
                s1=getarea(point[0][0],point[0][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(a*point[2][0]+b*point[2][1]+c==0)
                s1=getarea(point[1][0],point[1][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else
            {
                if(flag1==1&&flag2==1)
                    s1=getarea(point[0][0],point[0][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
                else if(flag1==1&&flag3==1)
                    s1=getarea(point[1][0],point[1][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
                else if(flag2==1&&flag3==1)
                    s1=getarea(point[2][0],point[2][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            }
            s2=s-s1;
            if(s1<=s2)
                System.out.print(" "+Judge.change(s1)+" "+Judge.change(s2));
            else
                System.out.print(" "+Judge.change(s2)+" "+Judge.change(s1));
        }
    }
}
class Quadrilateral
{
    Point point=new Point();
    Line line=new Line();
    Triangle triangle=new Triangle();
    public boolean judge(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
    {
        if(!point.adjacent(x1,y1,x2,y2,x3,y3,x4,y4))
            return false;
        if(triangle.judge(x1,y1,x2,y2,x3,y3,x4,y4))
            return false;
        return true;
    }
    public boolean parallelogram(double[][] points)
    {
        if(line.dis1(points[0][0],points[0][1],points[1][0],points[1][1])==line.dis1(points[3][0],points[3][1],points[2][0],points[2][1])&&line.parallel(points[0][0],points[0][1],points[1][0],points[1][1],points[3][0],points[3][1],points[2][0],points[2][1]))
            return true;
        else
            return false;
    }
    public boolean diamond(double[][] points)
    {
        double dis1,dis2,dis3,dis4;
        dis1=line.dis1(points[0][0],points[0][1],points[1][0],points[1][1]);
        dis2=line.dis1(points[2][0],points[2][1],points[1][0],points[1][1]);
        dis3=line.dis1(points[2][0],points[2][1],points[3][0],points[3][1]);
        dis4=line.dis1(points[0][0],points[0][1],points[3][0],points[3][1]);
        if(dis1==dis2&&dis1==dis3&&dis1==dis4)
            return true;
        else
            return false;
    }
    public boolean rectangle(double[][] points)
    {
        double xx1,xx2,xx3,yy1,yy2,yy3;
        xx1=points[1][0]-points[0][0];
        yy1=points[1][1]-points[0][1];
        xx2=points[3][0]-points[0][0];
        yy2=points[3][1]-points[0][1];
        xx3=points[2][0]-points[1][0];
        yy3=points[2][1]-points[1][1];
        if(xx1*xx2+yy1*yy2==0&&xx1*xx3+yy1*yy3==0)
            return true;
        else
            return false;
    }
    public boolean square(double[][] points)
    {
        if(this.diamond(points)&&this.rectangle(points))
            return true;
        else
            return false;
    }
    public boolean coincide(double[][] points)
    {
        double a,b,c;
        a=points[1][1]-points[0][1];
        b=points[0][0]-points[1][0];
        c=points[1][0]*points[0][1]-points[0][0]*points[1][1];
        if(a*points[2][0]+b*points[2][1]+c==0&&a*points[3][0]+b*points[3][1]+c==0)
            return true;
        if(a*points[2][0]+b*points[2][1]+c==0&&a*points[5][0]+b*points[5][1]+c==0)
            return true;
        if(a*points[3][0]+b*points[3][1]+c==0&&a*points[4][0]+b*points[4][1]+c==0)
            return true;
        if(a*points[4][0]+b*points[4][1]+c==0&&a*points[5][0]+b*points[5][1]+c==0)
            return true;
        return false;
    }
    public int aotu(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
    {
        int flag=0;
        if(triangle.inorout(x1,y1,x2,y2,x3,y3,x4,y4))
            flag=1;
        if(triangle.inorout(x2,y2,x1,y1,x3,y3,x4,y4))
            flag=2;
        if(triangle.inorout(x3,y3,x2,y2,x1,y1,x4,y4))
            flag=3;
        if(triangle.inorout(x4,y4,x2,y2,x3,y3,x1,y1))
            flag=4;
        if(triangle.judge(x1,y1,x2,y2,x3,y3,x4,y4))
            flag=-1;
        return flag;
    }
    public double girth(double[][] points)
    {
        double dis1,dis2,dis3,dis4,l;
        dis1=line.dis1(points[0][0],points[0][1],points[1][0],points[1][1]);
        dis2=line.dis1(points[1][0],points[1][1],points[2][0],points[2][1]);
        dis3=line.dis1(points[2][0],points[2][1],points[3][0],points[3][1]);
        dis4=line.dis1(points[0][0],points[0][1],points[3][0],points[3][1]);
        l=dis1+dis2+dis3+dis4;
        return l;
    }
    public double area(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
    {
        double s,ar1,ar2,ar3,ar4;
        ar1=triangle.getarea(x1,y1,x2,y2,x3,y3);
        ar2=triangle.getarea(x1,y1,x3,y3,x4,y4);
        ar3=triangle.getarea(x1,y1,x2,y2,x4,y4);
        ar4=triangle.getarea(x2,y2,x3,y3,x4,y4);
        if(aotu(x1,y1,x2,y2,x3,y3,x4,y4)==0||aotu(x1,y1,x2,y2,x3,y3,x4,y4)==1||aotu(x1,y1,x2,y2,x3,y3,x4,y4)==3)
            s=ar1+ar2;
        else if(aotu(x1,y1,x2,y2,x3,y3,x4,y4)==4)
            s=ar3+ar4;
        else
            s=(ar1+ar2+ar3+ar4)/2;
        return s;
    }
    public boolean inorout(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4,double x5,double y5)
    {
        double ar1,ar2,ar3,ar4,ar;
        ar1=triangle.getarea(x1,y1,x2,y2,x3,y3);
        ar2=triangle.getarea(x1,y1,x3,y3,x4,y4);
        ar3=triangle.getarea(x1,y1,x4,y4,x5,y5);
        ar4=triangle.getarea(x1,y1,x2,y2,x5,y5);
        ar=area(x2,y2,x3,y3,x4,y4,x5,y5);
        if(Math.abs(ar-ar4-ar3-ar2-ar1)<0.1)
            return true;
        else
            return false;
    }
    public void cut(double[][] points)
    {
        double s,s1=0,s2;
        int flag1=0,flag2=0,flag3=0,flag4=0;
        double a=points[1][1]-points[0][1];
        double b=points[0][0]-points[1][0];
        double c=points[1][0]*points[0][1]-points[0][0]*points[1][1];
        if(line.intersect(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1]))
            flag1=1;
        if(line.intersect(points[0][0],points[0][1],points[1][0],points[1][1],points[3][0],points[3][1],points[4][0],points[4][1]))
            flag2=1;
        if(line.intersect(points[0][0],points[0][1],points[1][0],points[1][1],points[4][0],points[4][1],points[5][0],points[5][1]))
            flag3=1;
        if(line.intersect(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[5][0],points[5][1]))
            flag4=1;
        System.out.print(line.k);
        s=area(points[2][0],points[2][1],points[3][0],points[3][1],points[4][0],points[4][1],points[5][0],points[5][1]);
        if(line.k==2)
        {
            if(a*points[2][0]+b*points[2][1]+c==0&&a*points[4][0]+b*points[4][1]+c==0)
                s1=triangle.getarea(points[3][0],points[3][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(a*points[3][0]+b*points[3][1]+c==0&&a*points[5][0]+b*points[5][1]+c==0)
                s1=triangle.getarea(points[2][0],points[2][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(a*points[2][0]+b*points[2][1]+c==0&&flag2==1)
                s1=triangle.getarea(points[3][0],points[3][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(a*points[2][0]+b*points[2][1]+c==0&&flag3==1)
                s1=triangle.getarea(points[5][0],points[5][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(a*points[3][0]+b*points[3][1]+c==0&&flag3==1)
                s1=triangle.getarea(points[4][0],points[4][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(a*points[3][0]+b*points[3][1]+c==0&&flag4==1)
                s1=triangle.getarea(points[2][0],points[2][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(a*points[4][0]+b*points[4][1]+c==0&&flag1==1)
                s1=triangle.getarea(points[3][0],points[3][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(a*points[4][0]+b*points[4][1]+c==0&&flag4==1)
                s1=triangle.getarea(points[5][0],points[5][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(a*points[5][0]+b*points[5][1]+c==0&&flag1==1)
                s1=triangle.getarea(points[2][0],points[2][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(a*points[5][0]+b*points[5][1]+c==0&&flag2==1)
                s1=triangle.getarea(points[4][0],points[4][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(flag1==1&&flag2==1)
                s1=triangle.getarea(points[3][0],points[3][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(flag1==1&&flag3==1)
                s1=area(points[3][0],points[3][1],points[4][0],points[4][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(flag1==1&&flag4==1)
                s1=triangle.getarea(points[2][0],points[2][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(flag2==1&&flag3==1)
                s1=triangle.getarea(points[4][0],points[4][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else if(flag2==1&&flag4==1)
                s1=area(points[2][0],points[2][1],points[3][0],points[3][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            else
                s1=triangle.getarea(points[5][0],points[5][1],line.cutPoint[0],line.cutPoint[1],line.cutPoint[2],line.cutPoint[3]);
            s2=s-s1;
            if(s1<=s2)
                System.out.print(" "+Judge.change(s1)+" "+Judge.change(s2));
            else
                System.out.print(" "+Judge.change(s2)+" "+Judge.change(s1));
        }
    }
}

类图:
img

SourceMonitor生成的报表内容:
img

本题心得:
虽然进行了分类处理,但是各个类的复用性不足,需要更进一步的重构,并且优化算法,省去不必要的、冗余的代码,使代码显得更简洁,易读性强。或许多边形的切割有简易的方法,但是本题还是采用了暴力解题,因此代码量较多。还有就是关于凹凸四边形的判断,其实可以用面积比较法来判断,一种将四边形ABCD分割成ABD、BCD,一种分割成ABC、ACD,比较两种面积之和,若不一致则为凹,一致则凸,下面求面积的时候,也可以用此方法,取面积之和最小的一种即可,这样的话比在此写的判断凹点的方法更简便。

③题集五

7-1 点线形系列5-凸五边形的计算-1

题目:
用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入五个点坐标,判断是否是五边形,判断结果输出true/false。
2:输入五个点坐标,判断是凹五边形(false)还是凸五边形(true),如果是凸五边形,则再输出五边形周长、面积,结果之间以一个英文空格符分隔。 若五个点坐标无法构成五边形,输出"not a pentagon"
3:输入七个点坐标,前两个点构成一条直线,后五个点构成一个凸五边形、凸四边形或凸三角形,输出直线与五边形、四边形或三角形相交的交点数量。如果交点有两个,再按面积从小到大输出被直线分割成两部分的面积(不换行)。若直线与多边形形的一条边线重合,输出"The line is coincide with one of the lines"。若后五个点不符合五边形输入,若前两点重合,输出"points coincide"。

以上3选项中,若输入的点无法构成多边形,则输出"not a polygon"。输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如:x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z不与xy都相邻,如:z x y s、x z s y、x s z y

输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。

输出格式:
基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0

题目分析:
本题相较于上题目集的四边形,点的输入顺序判断更为复杂,需要考虑不相邻的线段是否相交,若相交则说明构不成五边形,均不相交则成立。关于凹凸判断,可从各点是否均在另四点构成的四边形的外部这一方面入手。分割则比上题更为复杂,但还是可以考虑上各种情况从而暴力解决。

源码展示:

import java.util.Scanner;
import java.util.ArrayList;
public class Main
{
    public static void main(String[] args)
    {
        Scanner input=new Scanner(System.in);
        String str,s2;
        str=input.nextLine();
        Judge.cheek(str);
        String[] s1, s3, num;
        ArrayList<Point> InPoints=new ArrayList<>();
        ArrayList<Point> InPoints2=new ArrayList<>();
        int t,k=0;
        char a=str.charAt(0);
        s1 = str.split(":");
        s2 = s1[1];
        s3 = s2.split(" ");
        Point point=new Point();
        t=s3.length;
        for(String n:s3)
        {
            num = n.split(",");
            Point in=new Point(Double.parseDouble(num[0]),Double.parseDouble(num[1]));
            k++;
            if(t==5)
            {
                if(!point.repeat(in,InPoints))
                    InPoints.add(in);
            }
            else
            {
                if(k<=2)
                    InPoints.add(in);
                else
                {
                    if(!point.repeat(in,InPoints2))
                        InPoints2.add(in);
                }
            }
        }
        InPoints.addAll(InPoints2);
        for(int i=t-5;i<InPoints.size()-2;i++)
        {
            if(point.collinear2(InPoints.get(i),InPoints.get(i+1),InPoints.get(i+2)))
            {
                InPoints.remove(i+1);
                i--;
            }
        }
        if(point.collinear2(InPoints.get(InPoints.size()-1),InPoints.get(t-5),InPoints.get(t-4))&&InPoints.size()>=t-2)
        {
            InPoints.remove(t-5);
        }
        if(point.collinear2(InPoints.get(InPoints.size()-2),InPoints.get(InPoints.size()-1),InPoints.get(t-5))&&InPoints.size()>=t-2)
        {
            InPoints.remove(InPoints.size()-1);
        }
        Line line=new Line();
        Triangle triangle=new Triangle();
        Quadrilateral quadrilateral=new Quadrilateral();
        Pentagon pentagon=new Pentagon();
        switch (a)
        {
            case '1':
                if(InPoints.size()!=5)
                    System.out.print("false");
                else if(!pentagon.adjacent(InPoints))
                    System.out.print("false");
                else
                    System.out.print("true");
                break;
            case '2':
                if(InPoints.size()!=5)
                {
                    System.out.println("not a pentagon");
                    break;
                }
                else if(!pentagon.adjacent(InPoints))
                {
                    System.out.print("not a pentagon");
                    break;
                }
                if(pentagon.AoTu(InPoints.get(0),InPoints.get(1),InPoints.get(2),InPoints.get(3),InPoints.get(4))==0)
                {
                    double l=pentagon.GetGirth(InPoints);
                    double s=pentagon.GetArea(InPoints.get(0),InPoints.get(1),InPoints.get(2),InPoints.get(3),InPoints.get(4));
                    System.out.print("true "+Judge.change(l)+" "+Judge.change(s));
                }
                else
                    System.out.print("false");
                break;
            case '3':
                Judge.coincide(InPoints.get(0),InPoints.get(1));
                if(line.coincide(InPoints))
                {
                    System.out.print("The line is coincide with one of the lines");
                }
                else if(InPoints.size()==5)
                {
                    if(!triangle.adjacent(InPoints))
                    {
                        System.out.print("not a polygon");
                    }
                    else
                        triangle.cut(InPoints);
                }
                else if(InPoints.size()==6)
                {
                    if(!quadrilateral.adjacent(InPoints))
                    {
                        System.out.print("not a polygon");
                    }
                    else
                        quadrilateral.cut(InPoints);
                }
                else if(InPoints.size()==7)
                {
                    if(!pentagon.adjacent(InPoints))
                    {
                        System.out.print("not a polygon");
                    }
                    else
                        pentagon.cut(InPoints);
                }
                else
                {
                    System.out.print("not a polygon");
                    break;
                }
                break;
        }
    }
}
class Judge
{
    public static void cheek(String str)
    {
        String s2;
        String[] s1, s3, num;
        char a,b,c;
        a = str.charAt(0);
        b = str.charAt(1);
        c = str.charAt(str.length()-1);
        if (b != ':')
        {
            System.out.print("Wrong Format");
            System.exit(0);
        }
        else if (a < '1' || a > '3')
        {
            System.out.print("Wrong Format");
            System.exit(0);
        }
        else if(c < '0' || c > '9')
        {
            System.out.print("Wrong Format");
            System.exit(0);
        }
        else
        {
            s1 = str.split(":");
            if (s1.length != 2)
            {
                System.out.print("Wrong Format");
                System.exit(0);
            }
            s2 = s1[1];
            s3 = s2.split(" ");
            for (String i : s3)
            {
                num = i.split(",");
                if (num.length != 2)
                {
                    System.out.print("Wrong Format");
                    System.exit(0);
                }
                for (String j : num)
                    if (!j.matches("^[+-]?(0|[1-9][0-9]*(\\.\\d+)?|(0\\.\\d+)?)"))
                    {
                        System.out.print("Wrong Format");
                        System.exit(0);
                    }
            }
            if(s3.length!=5&&(a=='1'||a=='2'))
            {
                System.out.print("wrong number of points");
                System.exit(0);
            }
            else if(s3.length!=7&&a=='3')
            {
                System.out.print("wrong number of points");
                System.exit(0);
            }
        }
    }
    public static void coincide(Point n1,Point n2)
    {
        if(n1.getX()==n2.getX()&&n1.getY()==n2.getY())
        {
            System.out.print("points coincide");
            System.exit(0);
        }
    }
    public static double change(double s)
    {
        double ans;
        ans=Double.parseDouble(String.format("%.3f",s));
        return ans;
    }
}
class Point
{
    private double x,y;
    public Point()
    {

    }
    public Point(double x1,double y1)
    {
        this.x=x1;
        this.y=y1;
    }
    public double getX()
    {
        return this.x;
    }
    public double getY()
    {
        return this.y;
    }
    public boolean repeat(Point n,ArrayList<Point> points)
    {
        for(Point i:points)
        {
            if(n.getX()==i.getX()&&n.getY()==i.getY())
                return true;
        }
        return false;
    }
    public boolean collinear1(Point a,Point b,Point c)
    {
        Line line=new Line(a,c);
        if(line.getA()*b.getX()+line.getB()*b.getY()+line.getC()==0)
            return true;
        else
            return false;
    }
    public boolean collinear2(Point a,Point b,Point c)
    {
        Line line=new Line(a,c);
        if(line.getA()*b.getX()+line.getB()*b.getY()+line.getC()==0)
        {
            if((b.getX()-a.getX())*(b.getX()-c.getX())<0||(b.getY()-a.getY())*(b.getY()-c.getY())<0)
                return true;
        }
        return false;
    }
}
class Line
{
    public ArrayList<Point> cutPoints=new ArrayList<>();
    private double a,b,c;
    Point point=new Point();
    public Line()
    {

    }
    public Line(Point m,Point n)
    {
        this.a=n.getY()-m.getY();
        this.b=m.getX()-n.getX();
        this.c=n.getX()*m.getY()-m.getX()*n.getY();
    }
    public double getA()
    {
        return this.a;
    }
    public double getB()
    {
        return this.b;
    }
    public double getC()
    {
        return this.c;
    }
    public int intersect(Point n1,Point n2,Point n3,Point n4)
    {
        int flag;
        Line l1=new Line(n1,n2);
        Line l2=new Line(n3,n4);
        if(l1.getA()* l2.getB()-l2.getA()*l1.getB()==0)
            flag=0;
        else
        {
            double x=(l2.getB()*l1.getC()-l1.getB()*l2.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
            double y=(l1.getA()*l2.getC()-l2.getA()*l1.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
            if(((x-n1.getX())*(x-n2.getX())<0||(y-n1.getY())*(y-n2.getY())<0)&&((x-n3.getX())*(x-n4.getX())<0||(y-n3.getY())*(y-n4.getY())<0))
            {
                Point cut=new Point(x,y);
                if(!point.repeat(cut,cutPoints))
                    cutPoints.add(cut);
                flag=1;
            }
            else if((x-n3.getX())*(x-n4.getX())<=0&&(y-n3.getY())*(y-n4.getY())<=0)
            {
                Point cut=new Point(x,y);
                if(!point.repeat(cut,cutPoints))
                    cutPoints.add(cut);
                flag=2;
            }
            else
                flag=0;
        }
        return flag;
    }
    public double getDis(Point n1,Point n2)
    {
        double dis;
        dis=Math.sqrt((n1.getX()-n2.getX())*(n1.getX()-n2.getX())+(n1.getY()-n2.getY())*(n1.getY()-n2.getY()));
        return dis;
    }
    public boolean coincide(ArrayList<Point> points)
    {
        for(int i=2;i<points.size()-1;i++)
        {
            if(point.collinear1(points.get(0),points.get(1),points.get(i))&&point.collinear1(points.get(0),points.get(1),points.get(i+1)))
                return true;
        }
        if(point.collinear1(points.get(0),points.get(1),points.get(2))&&point.collinear1(points.get(0),points.get(1),points.get(points.size()-1)))
            return true;
        return false;
    }
}
class Triangle
{
    Point point=new Point();
    Line line=new Line();
    public boolean adjacent(ArrayList<Point> points)
    {
        int t=0;
        if(points.size()==5)
            t=2;
        if(point.collinear1(points.get(t),points.get(1+t),points.get(2+t)))
            return false;
        else
            return true;
    }
    public double GetArea(Point n1,Point n2,Point n3)
    {
        double l1,l2,l3,p,s;
        l1=Math.sqrt((n1.getX()-n2.getX())*(n1.getX()-n2.getX())+(n1.getY()-n2.getY())*(n1.getY()-n2.getY()));
        l2=Math.sqrt((n1.getX()-n3.getX())*(n1.getX()-n3.getX())+(n1.getY()-n3.getY())*(n1.getY()-n3.getY()));
        l3=Math.sqrt((n3.getX()-n2.getX())*(n3.getX()-n2.getX())+(n3.getY()-n2.getY())*(n3.getY()-n2.getY()));
        p=(l1+l2+l3)/2;
        s=Math.sqrt(p*(p-l1)*(p-l2)*(p-l3));
        return s;
    }
    public void cut(ArrayList<Point> points)
    {
        double s,s1,s2;
        int flag1=0,flag2=0,flag3=0;
        if(line.intersect(points.get(0),points.get(1),points.get(2),points.get(3))!=0)
            flag1=1;
        if(line.intersect(points.get(0),points.get(1),points.get(3),points.get(4))!=0)
            flag2=1;
        if(line.intersect(points.get(0),points.get(1),points.get(2),points.get(4))!=0)
            flag3=1;
        System.out.print(line.cutPoints.size());
        s=GetArea(points.get(2),points.get(3),points.get(4));
        if(line.cutPoints.size()==2)
        {
            if(point.repeat(points.get(2),line.cutPoints))
                s1=GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(3),line.cutPoints))
                s1=GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(4),line.cutPoints))
                s1=GetArea(points.get(4),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(flag1==1&&flag2==1)
                s1=GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(flag2==1&&flag3==1)
                s1=GetArea(points.get(4),line.cutPoints.get(0),line.cutPoints.get(1));
            else
                s1=GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1));
            s2=s-s1;
            if(s1<=s2)
                System.out.print(" "+Judge.change(s1)+" "+Judge.change(s2));
            else
                System.out.print(" "+Judge.change(s2)+" "+Judge.change(s1));
        }
    }
}
class Quadrilateral
{
    Point point=new Point();
    Line line=new Line();
    Triangle triangle=new Triangle();
    public boolean adjacent(ArrayList<Point> points)
    {
        int t=0;
        if(points.size()==6)
            t=2;
        double a1=points.get(2+t).getY()-points.get(t).getY();
        double a2=points.get(3+t).getY()-points.get(1+t).getY();
        double b1=points.get(t).getX()-points.get(2+t).getX();
        double b2=points.get(1+t).getX()-points.get(3+t).getX();
        double c1=points.get(2+t).getX()*points.get(t).getY()-points.get(t).getX()*points.get(2+t).getY();
        double c2=points.get(3+t).getX()*points.get(1+t).getY()-points.get(1+t).getX()*points.get(3+t).getY();
        if(a1*b2-a2*b1==0)
            return false;
        double x=(b2*c1-b1*c2)/(a2*b1-a1*b2);
        double y=(a1*c2-a2*c1)/(a2*b1-a1*b2);
        if((x-points.get(t).getX())*(x-points.get(2+t).getX())<0||(x-points.get(1+t).getX())*(x-points.get(3+t).getX())<0||(y-points.get(t).getY())*(y-points.get(2+t).getY())<0||(y-points.get(1+t).getY())*(y-points.get(3+t).getY())<0)
            return true;
        else
            return false;
    }
    public double GetArea(Point n1,Point n2,Point n3,Point n4)
    {
        double s,ar1,ar2,ar3,ar4,s1,s2;
        ar1=triangle.GetArea(n1,n2,n3);
        ar2=triangle.GetArea(n1,n3,n4);
        ar3=triangle.GetArea(n1,n2,n4);
        ar4=triangle.GetArea(n2,n3,n4);
        s1=ar1+ar2;
        s2=ar3+ar4;
        s=Math.min(s1,s2);
        return s;
    }
    public boolean InOrOut(Point n1,Point n2,Point n3,Point n4,Point n5)
    {
        double ar1,ar2,ar3,ar4,ar;
        ar1=triangle.GetArea(n1,n2,n3);
        ar2=triangle.GetArea(n1,n3,n4);
        ar3=triangle.GetArea(n1,n4,n5);
        ar4=triangle.GetArea(n1,n2,n5);
        ar=GetArea(n2,n3,n4,n5);
        if(Math.abs(ar-ar4-ar3-ar2-ar1)<0.1)
            return true;
        else
            return false;
    }
    public void cut(ArrayList<Point> points)
    {
        double s,s1,s2;
        int flag1=0,flag2=0,flag3=0,flag4=0;
        if(line.intersect(points.get(0),points.get(1),points.get(2),points.get(3))!=0)
            flag1=1;
        if(line.intersect(points.get(0),points.get(1),points.get(3),points.get(4))!=0)
            flag2=1;
        if(line.intersect(points.get(0),points.get(1),points.get(4),points.get(5))!=0)
            flag3=1;
        if(line.intersect(points.get(0),points.get(1),points.get(2),points.get(5))!=0)
            flag4=1;
        System.out.print(line.cutPoints.size());
        s=GetArea(points.get(2),points.get(3),points.get(4),points.get(5));
        if(line.cutPoints.size()==2)
        {
            if(point.repeat(points.get(2),line.cutPoints)&&point.repeat(points.get(4),line.cutPoints))
                s1=triangle.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(3),line.cutPoints)&&point.repeat(points.get(5),line.cutPoints))
                s1=triangle.GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(2),line.cutPoints)&&flag2==1)
                s1=triangle.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(2),line.cutPoints)&&flag3==1)
                s1=triangle.GetArea(points.get(5),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(3),line.cutPoints)&&flag3==1)
                s1=triangle.GetArea(points.get(4),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(3),line.cutPoints)&&flag4==1)
                s1=triangle.GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(4),line.cutPoints)&&flag1==1)
                s1=triangle.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(4),line.cutPoints)&&flag4==1)
                s1=triangle.GetArea(points.get(5),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(5),line.cutPoints)&&flag1==1)
                s1=triangle.GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(5),line.cutPoints)&&flag2==1)
                s1=triangle.GetArea(points.get(4),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(flag1==1&&flag2==1)
                s1=triangle.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(flag1==1&&flag3==1)
                s1=GetArea(line.cutPoints.get(0),line.cutPoints.get(1),points.get(4),points.get(3));
            else if(flag1==1&&flag4==1)
                s1=triangle.GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(flag2==1&&flag3==1)
                s1=triangle.GetArea(points.get(4),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(flag2==1&&flag4==1)
                s1=GetArea(line.cutPoints.get(0),line.cutPoints.get(1),points.get(2),points.get(3));
            else
                s1=triangle.GetArea(points.get(5),line.cutPoints.get(0),line.cutPoints.get(1));
            s2=s-s1;
            if(s1<=s2)
                System.out.print(" "+Judge.change(s1)+" "+Judge.change(s2));
            else
                System.out.print(" "+Judge.change(s2)+" "+Judge.change(s1));
        }
    }
}
class Pentagon
{
    Point point=new Point();
    Line line=new Line();
    Triangle triangle=new Triangle();
    Quadrilateral quadrilateral=new Quadrilateral();
    public boolean adjacent(ArrayList<Point> points)
    {
        int t=0;
        if(points.size()==7)
            t=2;
        Line line=new Line();
        if(point.collinear1(points.get(t),points.get(1+t),points.get(2+t)))
            return false;
        if(point.collinear1(points.get(1+t),points.get(2+t),points.get(3+t)))
            return false;
        if(point.collinear1(points.get(2+t),points.get(3+t),points.get(4+t)))
            return false;
        if(point.collinear1(points.get(3+t),points.get(4+t),points.get(t)))
            return false;
        if(point.collinear1(points.get(4+t),points.get(t),points.get(1+t)))
            return false;
        if(line.intersect(points.get(t),points.get(1+t),points.get(2+t),points.get(3+t))==1)
            return false;
        if(line.intersect(points.get(t),points.get(1+t),points.get(3+t),points.get(4+t))==1)
            return false;
        if(line.intersect(points.get(t),points.get(4+t),points.get(1+t),points.get(2+t))==1)
            return false;
        if(line.intersect(points.get(t),points.get(4+t),points.get(2+t),points.get(3+t))==1)
            return false;
        if(line.intersect(points.get(1+t),points.get(2+t),points.get(3+t),points.get(4+t))==1)
            return false;
        return true;
    }
    public int AoTu(Point n1,Point n2,Point n3,Point n4,Point n5)
    {
        int flag;
        if(quadrilateral.InOrOut(n1,n2,n3,n4,n5))
            flag=1;
        else if(quadrilateral.InOrOut(n2,n1,n3,n4,n5))
            flag=2;
        else if(quadrilateral.InOrOut(n3,n1,n2,n4,n5))
            flag=3;
        else if(quadrilateral.InOrOut(n4,n1,n2,n3,n5))
            flag=4;
        else if(quadrilateral.InOrOut(n5,n1,n2,n3,n4))
            flag=5;
        else
            flag=0;
        return flag;
    }
    public double GetGirth(ArrayList<Point> points)
    {
        double l,l1,l2,l3,l4,l5;
        l1=line.getDis(points.get(0),points.get(1));
        l2=line.getDis(points.get(1),points.get(2));
        l3=line.getDis(points.get(2),points.get(3));
        l4=line.getDis(points.get(3),points.get(4));
        l5=line.getDis(points.get(0),points.get(4));
        l=l1+l2+l3+l4+l5;
        return l;
    }
    public double GetArea(Point n1,Point n2,Point n3,Point n4,Point n5)
    {
        double ar;
        if(AoTu(n1,n2,n3,n4,n5)==1)
            ar=quadrilateral.GetArea(n2,n3,n4,n5)-triangle.GetArea(n1,n2,n5);
        else if(AoTu(n1,n2,n3,n4,n5)==2)
            ar=quadrilateral.GetArea(n1,n3,n4,n5)-triangle.GetArea(n1,n2,n3);
        else if(AoTu(n1,n2,n3,n4,n5)==3)
            ar=quadrilateral.GetArea(n1,n2,n4,n5)-triangle.GetArea(n2,n3,n4);
        else if(AoTu(n1,n2,n3,n4,n5)==4)
            ar=quadrilateral.GetArea(n1,n2,n3,n5)-triangle.GetArea(n3,n4,n5);
        else if(AoTu(n1,n2,n3,n4,n5)==5)
            ar=quadrilateral.GetArea(n1,n2,n3,n4)-triangle.GetArea(n1,n4,n5);
        else
            ar=triangle.GetArea(n1,n2,n5)+quadrilateral.GetArea(n2,n3,n4,n5);
        return ar;
    }
    public void cut(ArrayList<Point> points)
    {
        double s,s1,s2;
        int flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;
        if(line.intersect(points.get(0),points.get(1),points.get(2),points.get(3))!=0)
            flag1=1;
        if(line.intersect(points.get(0),points.get(1),points.get(3),points.get(4))!=0)
            flag2=1;
        if(line.intersect(points.get(0),points.get(1),points.get(4),points.get(5))!=0)
            flag3=1;
        if(line.intersect(points.get(0),points.get(1),points.get(5),points.get(6))!=0)
            flag4=1;
        if(line.intersect(points.get(0),points.get(1),points.get(2),points.get(6))!=0)
            flag5=1;
        System.out.print(line.cutPoints.size());
        s=GetArea(points.get(2),points.get(3),points.get(4),points.get(5),points.get(6));
        if(line.cutPoints.size()==2)
        {
            if(point.repeat(points.get(2),line.cutPoints)&&point.repeat(points.get(4),line.cutPoints))
                s1=triangle.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(2),line.cutPoints)&&point.repeat(points.get(5),line.cutPoints))
                s1=triangle.GetArea(points.get(6),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(3),line.cutPoints)&&point.repeat(points.get(6),line.cutPoints))
                s1=triangle.GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(3),line.cutPoints)&&point.repeat(points.get(5),line.cutPoints))
                s1=triangle.GetArea(points.get(4),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(4),line.cutPoints)&&point.repeat(points.get(6),line.cutPoints))
                s1=triangle.GetArea(points.get(5),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(2),line.cutPoints)&&flag2==1)
                s1=triangle.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(2),line.cutPoints)&&flag3==1)
                s1=quadrilateral.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1),points.get(4));
            else if(point.repeat(points.get(2),line.cutPoints)&&flag4==1)
                s1=triangle.GetArea(points.get(6),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(3),line.cutPoints)&&flag3==1)
                s1=triangle.GetArea(points.get(4),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(3),line.cutPoints)&&flag4==1)
                s1=quadrilateral.GetArea(points.get(4),line.cutPoints.get(0),line.cutPoints.get(1),points.get(5));
            else if(point.repeat(points.get(3),line.cutPoints)&&flag5==1)
                s1=triangle.GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(4),line.cutPoints)&&flag1==1)
                s1=triangle.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(4),line.cutPoints)&&flag5==1)
                s1=quadrilateral.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1),points.get(2));
            else if(point.repeat(points.get(4),line.cutPoints)&&flag4==1)
                s1=triangle.GetArea(points.get(5),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(5),line.cutPoints)&&flag2==1)
                s1=triangle.GetArea(points.get(4),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(5),line.cutPoints)&&flag1==1)
                s1=quadrilateral.GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1),points.get(6));
            else if(point.repeat(points.get(5),line.cutPoints)&&flag5==1)
                s1=triangle.GetArea(points.get(6),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(6),line.cutPoints)&&flag1==1)
                s1=triangle.GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(point.repeat(points.get(6),line.cutPoints)&&flag2==1)
                s1=quadrilateral.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1),points.get(2));
            else if(point.repeat(points.get(6),line.cutPoints)&&flag3==1)
                s1=triangle.GetArea(points.get(5),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(flag1==1&&flag2==1)
                s1=triangle.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(flag1==1&&flag3==1)
                s1=quadrilateral.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1),points.get(4));
            else if(flag1==1&&flag4==1)
                s1=quadrilateral.GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1),points.get(6));
            else if(flag1==1&&flag5==1)
                s1=triangle.GetArea(points.get(2),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(flag2==1&&flag3==1)
                s1=triangle.GetArea(points.get(4),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(flag2==1&&flag4==1)
                s1=quadrilateral.GetArea(points.get(4),line.cutPoints.get(0),line.cutPoints.get(1),points.get(5));
            else if(flag2==1&&flag5==1)
                s1=quadrilateral.GetArea(points.get(3),line.cutPoints.get(0),line.cutPoints.get(1),points.get(2));
            else if(flag3==1&&flag4==1)
                s1=triangle.GetArea(points.get(5),line.cutPoints.get(0),line.cutPoints.get(1));
            else if(flag3==1&&flag5==1)
                s1=quadrilateral.GetArea(points.get(5),line.cutPoints.get(0),line.cutPoints.get(1),points.get(6));
            else
                s1=triangle.GetArea(points.get(6),line.cutPoints.get(0),line.cutPoints.get(1));
            s2=s-s1;
            if(s1<=s2)
                System.out.print(" "+Judge.change(s1)+" "+Judge.change(s2));
            else
                System.out.print(" "+Judge.change(s2)+" "+Judge.change(s1));
        }
    }
}

类图:
img

SourceMonitor生成的报表内容:
img

本题心得:
冗余点的过滤可在输入的时候进行,这样对于接下来的选项处理则更简便了,比如若输入的点出现重复,则不记录在Arraylist中,接着处理多点共线,将线段中间的点删除,从而去除冗余点。由SourceMonitor生成的报表内容可看出,比以往优化了很多,几个方面点没有超出范围,但是仍需要优化。

7-2 点线形系列5-凸五边形的计算-2

题目:
用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
4:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),判断它们两个之间是否存在包含关系(一个多边形有一条或多条边与另一个多边形重合,其他部分都包含在另一个多边形内部,也算包含)。
两者存在六种关系:1、分离(完全无重合点) 2、连接(只有一个点或一条边重合) 3、完全重合 4、被包含(前一个多边形在后一个多边形的内部)5、交错 6、包含(后一个多边形在前一个多边形的内部)。
各种关系的输出格式如下:
1、no overlapping area between the previous triangle/quadrilateral/ pentagon and the following triangle/quadrilateral/ pentagon
2、the previous triangle/quadrilateral/ pentagon is connected to the following triangle/quadrilateral/ pentagon
3、the previous triangle/quadrilateral/ pentagon coincides with the following triangle/quadrilateral/ pentagon
4、the previous triangle/quadrilateral/ pentagon is inside the following triangle/quadrilateral/ pentagon
5、the previous triangle/quadrilateral/ pentagon is interlaced with the following triangle/quadrilateral/ pentagon
6、the previous triangle/quadrilateral/ pentagon contains the following triangle/quadrilateral/ pentagon

5:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),输出两个多边形公共区域的面积。注:只考虑每个多边形被另一个多边形分割成最多两个部分的情况,不考虑一个多边形将另一个分割成超过两个区域的情况。
6:输入六个点坐标,输出第一个是否在后五个点所构成的多边形(限定为凸多边形,不考虑凹多边形),的内部(若是五边形输出in the pentagon/outof the pentagon,若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。输入入错存在冗余点要排除,冗余点的判定方法见选项5。如果点在多边形的某条边上,输出"on the triangle/on the quadrilateral/on the pentagon"。
以上4、5、6选项输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如:x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z不与xy都相邻,如:z x y s、x z s y、x s z y

输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。

输出格式:
输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0

题目分析:
本题的重点是两个多边形的各点之间的位置关系处理。可以先完成选项6,接着完成选项4,最后在处理选项5。选项6最简单,通过点与多边形形成的多个三角形之和与多边形总面积进行比较判断。选项4则根据点的位置,例如点在外部个数,点在内部个数,点在多边形上个数,线段重合等进行数形结合的判断。选项5则需要获取公共区域的各点坐标,并进行排序,如不进行排序,则无法正确得出面积。

源码展示:

import java.util.Scanner;
import java.util.ArrayList;
public class Main
{
    public static void main(String[] args)
    {
        Scanner input=new Scanner(System.in);
        String str,s2;
        str=input.nextLine();
        Judge.cheek(str);
        String[] s1, s3, num;
        ArrayList<Point> InPoints=new ArrayList<>();
        ArrayList<Point> InPoints2=new ArrayList<>();
        int t,k=0;
        char a=str.charAt(0);
        s1 = str.split(":");
        s2 = s1[1];
        s3 = s2.split(" ");
        Point point=new Point();
        Line line=new Line();
        Triangle triangle=new Triangle();
        Quadrilateral quadrilateral=new Quadrilateral();
        Pentagon pentagon=new Pentagon();
        Relation relation=new Relation();
        Relation relation2=new Relation();
        t=s3.length;
        for(String n:s3)
        {
            num = n.split(",");
            Point in=new Point(Double.parseDouble(num[0]),Double.parseDouble(num[1]));
            k++;
            if(t==10)
            {
                if(k<=5)
                {
                    if(!point.repeat(in,InPoints))
                        InPoints.add(in);
                }
                else
                {
                    if(!point.repeat(in,InPoints2))
                        InPoints2.add(in);
                }
            }
            else
            {
                if(k<=1)
                    InPoints.add(in);
                else
                {
                    if(!point.repeat(in,InPoints2))
                        InPoints2.add(in);
                }
            }
        }
        for(int i=0;i<InPoints.size()-2;i++)
        {
            if(point.collinear2(InPoints.get(i),InPoints.get(i+1),InPoints.get(i+2)))
            {
                InPoints.remove(i+1);
                i--;
            }
        }
        if(InPoints.size()>=3&&point.collinear2(InPoints.get(InPoints.size()-1),InPoints.get(0),InPoints.get(1)))
        {
            InPoints.remove(0);
        }
        if(InPoints.size()>=3&&point.collinear2(InPoints.get(InPoints.size()-2),InPoints.get(InPoints.size()-1),InPoints.get(0)))
        {
            InPoints.remove(InPoints.size()-1);
        }
        for(int i=0;i<InPoints2.size()-2;i++)
        {
            if(point.collinear2(InPoints2.get(i),InPoints2.get(i+1),InPoints2.get(i+2)))
            {
                InPoints2.remove(i+1);
                i--;
            }
        }
        if(InPoints2.size()>=3&&point.collinear2(InPoints2.get(InPoints2.size()-1),InPoints2.get(0),InPoints2.get(1)))
        {
            InPoints2.remove(0);
        }
        if(InPoints2.size()>=3&&point.collinear2(InPoints2.get(InPoints2.size()-2),InPoints2.get(InPoints2.size()-1),InPoints2.get(0)))
        {
            InPoints2.remove(InPoints2.size()-1);
        }
        switch (a)
        {
            case '4':
                relation.getCount(InPoints,InPoints2);
                relation2.getCount(InPoints2,InPoints);
                if(relation.out==InPoints.size()&&relation2.out==InPoints2.size())
                {
                    System.out.print("no overlapping area between the previous ");
                    if(InPoints.size()==3)
                        System.out.print("triangle and the following ");
                    else if(InPoints.size()==4)
                        System.out.print("quadrilateral and the following ");
                    else
                        System.out.print("pentagon and the following ");
                    if(InPoints2.size()==3)
                        System.out.print("triangle");
                    else if(InPoints2.size()==4)
                        System.out.print("quadrilateral");
                    else
                        System.out.print("pentagon");
                }
                else if(relation.on==InPoints.size()&&relation2.on==InPoints2.size())
                {
                    System.out.print("the previous ");
                    if(InPoints.size()==3)
                        System.out.print("triangle coincides with the following ");
                    else if(InPoints.size()==4)
                        System.out.print("quadrilateral coincides with the following ");
                    else
                        System.out.print("pentagon coincides with the following ");
                    if(InPoints2.size()==3)
                        System.out.print("triangle");
                    else if(InPoints2.size()==4)
                        System.out.print("quadrilateral");
                    else
                        System.out.print("pentagon");
                }
                else if(relation.out==0)
                {
                    System.out.print("the previous ");
                    if(InPoints.size()==3)
                        System.out.print("triangle is inside the following ");
                    else if(InPoints.size()==4)
                        System.out.print("quadrilateral is inside the following ");
                    else
                        System.out.print("pentagon is inside the following ");
                    if(InPoints2.size()==3)
                        System.out.print("triangle");
                    else if(InPoints2.size()==4)
                        System.out.print("quadrilateral");
                    else
                        System.out.print("pentagon");
                }
                else if(relation2.out==0)
                {
                    System.out.print("the previous ");
                    if(InPoints.size()==3)
                        System.out.print("triangle contains the following ");
                    else if(InPoints.size()==4)
                        System.out.print("quadrilateral contains the following ");
                    else
                        System.out.print("pentagon contains the following ");
                    if(InPoints2.size()==3)
                        System.out.print("triangle");
                    else if(InPoints2.size()==4)
                        System.out.print("quadrilateral");
                    else
                        System.out.print("pentagon");
                }
                else if(relation.coincide(relation.OnPoints,InPoints2)&&relation.in==0&&relation2.in==0)
                {
                    System.out.print("the previous ");
                    if(InPoints.size()==3)
                        System.out.print("triangle is connected to the following ");
                    else if(InPoints.size()==4)
                        System.out.print("quadrilateral is connected to the following ");
                    else
                        System.out.print("pentagon is connected to the following ");
                    if(InPoints2.size()==3)
                        System.out.print("triangle");
                    else if(InPoints2.size()==4)
                        System.out.print("quadrilateral");
                    else
                        System.out.print("pentagon");
                }
                else
                {
                    System.out.print("the previous ");
                    if(InPoints.size()==3)
                        System.out.print("triangle is interlaced with the following ");
                    else if(InPoints.size()==4)
                        System.out.print("quadrilateral is interlaced with the following ");
                    else
                        System.out.print("pentagon is interlaced with the following ");
                    if(InPoints2.size()==3)
                        System.out.print("triangle");
                    else if(InPoints2.size()==4)
                        System.out.print("quadrilateral");
                    else
                        System.out.print("pentagon");
                }
                break;
            case '5':
                double s;
                relation.getCount(InPoints,InPoints2);
                relation2.getCount(InPoints2,InPoints);
                Cut cut=new Cut();
                ArrayList<Point> cutPoints=new ArrayList<>();
                cutPoints.addAll(relation.InPoints);
                cutPoints.addAll(relation.OnPoints);
                cutPoints.addAll(relation2.InPoints);
                cut.sort(cutPoints);
                s= cut.getArea(cutPoints);
                System.out.print(Judge.change(s));
                break;
            case '6':
                if(InPoints2.size()==3&&triangle.isOn(InPoints.get(0),InPoints2))
                    System.out.print("on the triangle");
                else if(InPoints2.size()==3&&triangle.InOrOut(InPoints.get(0),InPoints2.get(0),InPoints2.get(1),InPoints2.get(2)))
                    System.out.print("in the triangle");
                else if(InPoints2.size()==3&&!triangle.InOrOut(InPoints.get(0),InPoints2.get(0),InPoints2.get(1),InPoints2.get(2)))
                    System.out.print("outof the triangle");
                else if(InPoints2.size()==4&&quadrilateral.isOn(InPoints.get(0),InPoints2))
                    System.out.print("on the quadrilateral");
                else if(InPoints2.size()==4&&quadrilateral.InOrOut(InPoints.get(0),InPoints2.get(0),InPoints2.get(1),InPoints2.get(2),InPoints2.get(3)))
                    System.out.print("in the quadrilateral");
                else if(InPoints2.size()==4&&!quadrilateral.InOrOut(InPoints.get(0),InPoints2.get(0),InPoints2.get(1),InPoints2.get(2),InPoints2.get(3)))
                    System.out.print("outof the quadrilateral");
                else if(InPoints2.size()==5&&pentagon.isOn(InPoints.get(0),InPoints2))
                    System.out.print("on the pentagon");
                else if(InPoints2.size()==5&&pentagon.InOrOut(InPoints.get(0),InPoints2.get(0),InPoints2.get(1),InPoints2.get(2),InPoints2.get(3),InPoints2.get(4)))
                    System.out.print("in the pentagon");
                else
                    System.out.print("outof the pentagon");
                break;
        }
    }
}
class Judge
{
    public static void cheek(String str)
    {
        String s2;
        String[] s1, s3, num;
        char a,b,c;
        a = str.charAt(0);
        b = str.charAt(1);
        c = str.charAt(str.length()-1);
        if (b != ':')
        {
            System.out.print("Wrong Format");
            System.exit(0);
        }
        else if (a < '4' || a > '6')
        {
            System.out.print("Wrong Format");
            System.exit(0);
        }
        else if(c < '0' || c > '9')
        {
            System.out.print("Wrong Format");
            System.exit(0);
        }
        else
        {
            s1 = str.split(":");
            if (s1.length != 2)
            {
                System.out.print("Wrong Format");
                System.exit(0);
            }
            s2 = s1[1];
            s3 = s2.split(" ");
            for (String i : s3)
            {
                num = i.split(",");
                if (num.length != 2)
                {
                    System.out.print("Wrong Format");
                    System.exit(0);
                }
                for (String j : num)
                    if (!j.matches("^[+-]?(0|[1-9][0-9]*(\\.\\d+)?|(0\\.\\d+)?)"))
                    {
                        System.out.print("Wrong Format");
                        System.exit(0);
                    }
            }
            if(s3.length!=10&&(a=='4'||a=='5'))
            {
                System.out.print("wrong number of points");
                System.exit(0);
            }
            else if(s3.length!=6&&a=='6')
            {
                System.out.print("wrong number of points");
                System.exit(0);
            }
        }
    }
    public static double change(double s)
    {
        double ans;
        ans=Double.parseDouble(String.format("%.3f",s));
        return ans;
    }
}
class Point
{
    private double x,y;
    public Point()
    {

    }
    public Point(double x1,double y1)
    {
        this.x=x1;
        this.y=y1;
    }
    public double getX()
    {
        return this.x;
    }
    public double getY()
    {
        return this.y;
    }
    public void setX(double num)
    {
        this.x=num;
    }
    public void setY(double num)
    {
        this.y=num;
    }
    public boolean repeat(Point n,ArrayList<Point> points)
    {
        for(Point i:points)
        {
            if(n.getX()==i.getX()&&n.getY()==i.getY())
                return true;
        }
        return false;
    }
    public boolean collinear1(Point a,Point b,Point c)
    {
        Line line=new Line(a,c);
        if(line.getA()*b.getX()+line.getB()*b.getY()+line.getC()==0)
            return true;
        else
            return false;
    }
    public boolean collinear2(Point a,Point b,Point c)
    {
        Line line=new Line(a,c);
        if(line.getA()*b.getX()+line.getB()*b.getY()+line.getC()==0)
        {
            if((b.getX()-a.getX())*(b.getX()-c.getX())<0||(b.getY()-a.getY())*(b.getY()-c.getY())<0)
                return true;
        }
        return false;
    }
}
class Line
{
    public ArrayList<Point> cutPoints=new ArrayList<>();
    private double a,b,c;
    Point point=new Point();
    public Line()
    {

    }
    public Line(Point m,Point n)
    {
        this.a=n.getY()-m.getY();
        this.b=m.getX()-n.getX();
        this.c=n.getX()*m.getY()-m.getX()*n.getY();
    }
    public double getA()
    {
        return this.a;
    }
    public double getB()
    {
        return this.b;
    }
    public double getC()
    {
        return this.c;
    }
    public int intersect(Point n1,Point n2,Point n3,Point n4)
    {
        int flag;
        Line l1=new Line(n1,n2);
        Line l2=new Line(n3,n4);
        if(l1.getA()* l2.getB()-l2.getA()*l1.getB()==0)
            flag=0;
        else
        {
            double x=(l2.getB()*l1.getC()-l1.getB()*l2.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
            double y=(l1.getA()*l2.getC()-l2.getA()*l1.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
            if((x-n1.getX())*(x-n2.getX())<=0&&(y-n1.getY())*(y-n2.getY())<=0&&(x-n3.getX())*(x-n4.getX())<=0&&(y-n3.getY())*(y-n4.getY())<=0)
            {
                Point cut=new Point(x,y);
                if(!point.repeat(cut,cutPoints))
                    cutPoints.add(cut);
                flag=1;
            }
            else
                flag=0;
        }
        return flag;
    }
    public boolean coincide(Point n1,Point n2,Point n3,Point n4)
    {
        if(point.collinear1(n1,n3,n4)&&point.collinear1(n2,n3,n4))
            return true;
        return false;
    }
    public boolean isOn(Point n,Point n1,Point n2)
    {
        Line l=new Line(n1,n2);
        if(l.getA()*n.getX()+l.getB()*n.getY()+l.getC()==0)
        {
            if((n.getX()-n1.getX())*(n.getX()-n2.getX())<=0&&(n.getY()-n1.getY())*(n.getY()-n2.getY())<=0)
                return true;
        }
        return false;
    }
}
class Triangle
{
    Line line=new Line();
    public double GetArea(Point n1,Point n2,Point n3)
    {
        double l1,l2,l3,p,s;
        l1=Math.sqrt((n1.getX()-n2.getX())*(n1.getX()-n2.getX())+(n1.getY()-n2.getY())*(n1.getY()-n2.getY()));
        l2=Math.sqrt((n1.getX()-n3.getX())*(n1.getX()-n3.getX())+(n1.getY()-n3.getY())*(n1.getY()-n3.getY()));
        l3=Math.sqrt((n3.getX()-n2.getX())*(n3.getX()-n2.getX())+(n3.getY()-n2.getY())*(n3.getY()-n2.getY()));
        p=(l1+l2+l3)/2;
        s=Math.sqrt(p*(p-l1)*(p-l2)*(p-l3));
        return s;
    }
    public boolean isOn(Point n1,ArrayList<Point> points)
    {
        if(line.isOn(n1,points.get(0),points.get(1)))
            return true;
        else if(line.isOn(n1,points.get(1),points.get(2)))
            return true;
        else if(line.isOn(n1,points.get(0),points.get(2)))
            return true;
        else
            return false;
    }
    public boolean InOrOut(Point n1,Point n2,Point n3,Point n4)
    {
        double ar1,ar2,ar3,ar;
        ar1=GetArea(n1,n2,n3);
        ar2=GetArea(n1,n3,n4);
        ar3=GetArea(n1,n2,n4);
        ar=GetArea(n2,n3,n4);
        if(Math.abs(ar-ar3-ar2-ar1)<0.01)
            return true;
        else
            return false;
    }
}
class Quadrilateral
{
    Line line=new Line();
    Triangle triangle=new Triangle();
    public double GetArea(Point n1,Point n2,Point n3,Point n4)
    {
        double s,ar1,ar2,ar3,ar4,s1,s2;
        ar1=triangle.GetArea(n1,n2,n3);
        ar2=triangle.GetArea(n1,n3,n4);
        ar3=triangle.GetArea(n1,n2,n4);
        ar4=triangle.GetArea(n2,n3,n4);
        s1=ar1+ar2;
        s2=ar3+ar4;
        s=Math.min(s1,s2);
        return s;
    }
    public boolean isOn(Point n1,ArrayList<Point> points)
    {
        if(line.isOn(n1,points.get(0),points.get(1)))
            return true;
        else if(line.isOn(n1,points.get(1),points.get(2)))
            return true;
        else if(line.isOn(n1,points.get(2),points.get(3)))
            return true;
        else if(line.isOn(n1,points.get(0),points.get(3)))
            return true;
        else
            return false;
    }
    public boolean InOrOut(Point n1,Point n2,Point n3,Point n4,Point n5)
    {
        double ar1,ar2,ar3,ar4,ar;
        ar1=triangle.GetArea(n1,n2,n3);
        ar2=triangle.GetArea(n1,n3,n4);
        ar3=triangle.GetArea(n1,n4,n5);
        ar4=triangle.GetArea(n1,n2,n5);
        ar=GetArea(n2,n3,n4,n5);
        if(Math.abs(ar-ar4-ar3-ar2-ar1)<0.01)
            return true;
        else
            return false;
    }
}
class Pentagon
{
    Line line=new Line();
    Triangle triangle=new Triangle();
    Quadrilateral quadrilateral=new Quadrilateral();
    public int AoTu(Point n1,Point n2,Point n3,Point n4,Point n5)
    {
        int flag;
        if(quadrilateral.InOrOut(n1,n2,n3,n4,n5))
            flag=1;
        else if(quadrilateral.InOrOut(n2,n1,n3,n4,n5))
            flag=2;
        else if(quadrilateral.InOrOut(n3,n1,n2,n4,n5))
            flag=3;
        else if(quadrilateral.InOrOut(n4,n1,n2,n3,n5))
            flag=4;
        else if(quadrilateral.InOrOut(n5,n1,n2,n3,n4))
            flag=5;
        else
            flag=0;
        return flag;
    }
    public double GetArea(Point n1,Point n2,Point n3,Point n4,Point n5)
    {
        double ar;
        if(AoTu(n1,n2,n3,n4,n5)==1)
            ar=quadrilateral.GetArea(n2,n3,n4,n5)-triangle.GetArea(n1,n2,n5);
        else if(AoTu(n1,n2,n3,n4,n5)==2)
            ar=quadrilateral.GetArea(n1,n3,n4,n5)-triangle.GetArea(n1,n2,n3);
        else if(AoTu(n1,n2,n3,n4,n5)==3)
            ar=quadrilateral.GetArea(n1,n2,n4,n5)-triangle.GetArea(n2,n3,n4);
        else if(AoTu(n1,n2,n3,n4,n5)==4)
            ar=quadrilateral.GetArea(n1,n2,n3,n5)-triangle.GetArea(n3,n4,n5);
        else if(AoTu(n1,n2,n3,n4,n5)==5)
            ar=quadrilateral.GetArea(n1,n2,n3,n4)-triangle.GetArea(n1,n4,n5);
        else
            ar=triangle.GetArea(n1,n2,n5)+quadrilateral.GetArea(n2,n3,n4,n5);
        return ar;
    }
    public boolean isOn(Point n1,ArrayList<Point> points)
    {
        if(line.isOn(n1,points.get(0),points.get(1)))
            return true;
        else if(line.isOn(n1,points.get(1),points.get(2)))
            return true;
        else if(line.isOn(n1,points.get(2),points.get(3)))
            return true;
        else if(line.isOn(n1,points.get(3),points.get(4)))
            return true;
        else if(line.isOn(n1,points.get(0),points.get(4)))
            return true;
        else
            return false;
    }
    public boolean InOrOut(Point n1,Point n2,Point n3,Point n4,Point n5,Point n6)
    {
        double s1,s2,s3,s4,s5,s;
        s1=triangle.GetArea(n1,n2,n3);
        s2=triangle.GetArea(n1,n3,n4);
        s3=triangle.GetArea(n1,n4,n5);
        s4=triangle.GetArea(n1,n5,n6);
        s5=triangle.GetArea(n1,n2,n6);
        s=GetArea(n2,n3,n4,n5,n6);
        if(Math.abs(s-s1-s2-s3-s4-s5)<0.01)
            return true;
        else
            return false;
    }
}
class Relation
{
    public int on=0,in=0,out=0;
    public ArrayList<Point> InPoints=new ArrayList<>();
    public ArrayList<Point> OutPoints=new ArrayList<>();
    public ArrayList<Point> OnPoints=new ArrayList<>();
    Point point=new Point();
    Line line=new Line();
    Triangle triangle=new Triangle();
    Quadrilateral quadrilateral=new Quadrilateral();
    Pentagon pentagon=new Pentagon();
    public void getCount(ArrayList<Point> points1,ArrayList<Point> points2)
    {
        for(Point i:points1)
        {
            if(points2.size()==3)
            {
                if(triangle.isOn(i,points2))
                {
                    on++;
                }
                else if(triangle.InOrOut(i,points2.get(0),points2.get(1),points2.get(2)))
                {
                    in++;
                    if(!point.repeat(i,InPoints))
                        InPoints.add(i);
                }
                else
                {
                    out++;
                    if(!point.repeat(i,OutPoints))
                        OutPoints.add(i);
                }
            }
            else if(points2.size()==4)
            {
                if(quadrilateral.isOn(i,points2))
                {
                    on++;
                }
                else if(quadrilateral.InOrOut(i,points2.get(0),points2.get(1),points2.get(2),points2.get(3)))
                {
                    in++;
                    if(!point.repeat(i,InPoints))
                        InPoints.add(i);
                }
                else
                {
                    out++;
                    if(!point.repeat(i,OutPoints))
                        OutPoints.add(i);
                }
            }
            else
            {
                if(pentagon.isOn(i,points2))
                {
                    on++;
                }
                else if(pentagon.InOrOut(i,points2.get(0),points2.get(1),points2.get(2),points2.get(3),points2.get(4)))
                {
                    in++;
                    if(!point.repeat(i,InPoints))
                        InPoints.add(i);
                }
                else
                {
                    out++;
                    if(!point.repeat(i,OutPoints))
                        OutPoints.add(i);
                }
            }
        }
        double x,y;
        for(int i=0;i<points1.size()-1;i++)
        {
            for(int j=0;j<points2.size()-1;j++)
            {
                if(line.intersect(points1.get(i),points1.get(i+1),points2.get(j),points2.get(j+1))==1)
                {
                    Line l1=new Line(points1.get(i),points1.get(i+1));
                    Line l2=new Line(points2.get(j),points2.get(j+1));
                    x=(l2.getB()*l1.getC()-l1.getB()*l2.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
                    y=(l1.getA()*l2.getC()-l2.getA()*l1.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
                    Point n=new Point(x,y);
                    if(!point.repeat(n,OnPoints))
                        OnPoints.add(n);
                }
            }
            if(line.intersect(points1.get(i),points1.get(i+1),points2.get(0),points2.get(points2.size()-1))==1)
            {
                Line l1=new Line(points1.get(i),points1.get(i+1));
                Line l2=new Line(points2.get(0),points2.get(points2.size()-1));
                x=(l2.getB()*l1.getC()-l1.getB()*l2.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
                y=(l1.getA()*l2.getC()-l2.getA()*l1.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
                Point n=new Point(x,y);
                if(!point.repeat(n,OnPoints))
                    OnPoints.add(n);
            }
        }
        for(int i=0;i<points2.size()-1;i++)
        {
            if(line.intersect(points1.get(0),points1.get(points1.size()-1),points2.get(i),points2.get(i+1))==1)
            {
                Line l1=new Line(points1.get(0),points1.get(points1.size()-1));
                Line l2=new Line(points2.get(i),points2.get(i+1));
                x=(l2.getB()*l1.getC()-l1.getB()*l2.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
                y=(l1.getA()*l2.getC()-l2.getA()*l1.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
                Point n=new Point(x,y);
                if(!point.repeat(n,OnPoints))
                    OnPoints.add(n);
            }
        }
        if(line.intersect(points1.get(0),points1.get(points1.size()-1),points2.get(0),points2.get(points2.size()-1))==1)
        {
            Line l1=new Line(points1.get(0),points1.get(points1.size()-1));
            Line l2=new Line(points2.get(0),points2.get(points2.size()-1));
            x=(l2.getB()*l1.getC()-l1.getB()*l2.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
            y=(l1.getA()*l2.getC()-l2.getA()*l1.getC())/(l2.getA()*l1.getB()-l1.getA()*l2.getB());
            Point n=new Point(x,y);
            if(!point.repeat(n,OnPoints))
                OnPoints.add(n);
        }
    }
    public boolean coincide(ArrayList<Point> points,ArrayList<Point> points2)
    {
        if(points.size()==1)
            return true;
        else if(points.size()==2)
        {
            for(int i=0;i<points2.size()-1;i++)
            {
                if(line.coincide(points.get(0),points.get(1),points2.get(i),points2.get(i+1)))
                    return true;
            }
            if(line.coincide(points.get(0),points.get(1),points2.get(0),points2.get(points2.size()-1)))
                return true;
        }
        return false;
    }
}
class Cut
{
    Triangle triangle=new Triangle();
    public Point getCenter(ArrayList<Point> points)
    {
        double x=0;
        double y=0;
        for(Point i:points)
        {
            x+=i.getX();
            y+=i.getY();
        }
        x=x/points.size();
        y=y/points.size();
        Point n;
        n = new Point(x,y);
        return n;
    }
    public boolean compare(Point n,Point n1,Point n2)
    {
        if((n1.getX()- n.getX())*(n2.getY()- n.getY())-(n2.getX()- n.getX())*(n1.getY()- n.getY())>0)
            return false;
        else
            return true;
    }
    public void sort(ArrayList<Point> points)
    {
        Point n=getCenter(points);
        Point temp=new Point();
        for(int i=1;i<points.size();i++)
        {
            for(int j=0;j<points.size()-i;j++)
            {
                if(compare(n,points.get(j),points.get(j+1)))
                {
                    temp.setX(points.get(j).getX());
                    temp.setY(points.get(j).getY());
                    points.get(j).setX(points.get(j+1).getX());
                    points.get(j).setY(points.get(j+1).getY());
                    points.get(j+1).setX(temp.getX());
                    points.get(j+1).setY(temp.getY());
                }
            }
        }
    }
    public double getArea(ArrayList<Point> points)
    {
        double s=0;
        Point n=getCenter(points);
        for(int i=0;i<points.size()-1;i++)
            s+=triangle.GetArea(n,points.get(i),points.get(i+1));
        s+=triangle.GetArea(n,points.get(0),points.get(points.size()-1));
        return s;
    }
}

类图:
img

SourceMonitor生成的报表内容:
img

本题心得:
这题如果能够数形结合,那么解此题会更加方便,画图能使你明确看出多边形与多边形之间的位置关系,从中找出特点进行处理判断。关于坐标点的排序,可以利用向量的叉积进行判断排序,找出多边形的内点,然后以此为基准进行判断处理,排完序后便能分割成多个三角形相加得出面积。
因为算法没有得到太大的优化,且有冗余的代码存在,导致圈复杂度不是非常理想,且复用性不足,比上题的代码质量更差一些。需要重构。

③期中测试

7-1 点与线(类设计)

题目:

  • 设计一个类表示平面直角坐标系上的点Point,私有属性分别为横坐标x与纵坐标y,数据类型均为实型数,除构造方法以及属性的getter与setter方法外,定义一个用于显示信息的方法display(),用来输出该坐标点的坐标信息,格式如下:(x,y),数值保留两位小数。为简化题目,其中,坐标点的取值范围设定为 (0,200]。若输入有误,系统则直接输出 Wrong Format

  • 设计一个类表示平面直角坐标系上的线Line,私有属性除了标识线段两端的点point1、point2外,还有一个字符串类型的color,用于表示该线段的颜色,同样,除构造方法以及属性的getter与setter方法外,定义一个用于计算该线段长度的方法getDistance(),还有一个用于显示信息的方法display(),用来输出线段的相关信息,输出格式如下:

    The line's color is:颜色值
    The line's begin point's Coordinate is:
    (x1,y1)
    The line's end point's Coordinate is:
    (x2,y2)
    The line's length is:长度值
    

    其中,所有数值均保留两位小数,建议可用String.format("%.2f", data)方法。
    设计类图如下图所示。
    img

    ** 题目要求:在主方法中定义一条线段对象,从键盘输入该线段的起点坐标与终点坐标以及颜色,然后调用该线段的display()方法进行输出。 **

  • 以下情况为无效作业

    • 无法运行
    • 设计不符合所给类图要求
    • 未通过任何测试点测试
    • 判定为抄袭

输入格式:
分别输入线段的起点横坐标、纵坐标、终点的横坐标、纵坐标以及颜色,中间可用一个或多个空格、tab或者回车分隔。

输出格式:

The line's color is:颜色值
The line's begin point's Coordinate is:
(x1,y1)
The line's end point's Coordinate is:
(x2,y2)
The line's length is:长度值

题目分析:
本题难度不大,主要是基本的分类设计、构造,需要注意的点是输入点坐标值的判断,若输出范围错误,则输出Wrong Format。

源码展示:

import java.util.Scanner;

public class Main
{
    public static void main(String[] args)
    {
        double x1,x2,y1,y2;
        String color;
        Scanner input=new Scanner(System.in);
        x1= input.nextDouble();
        y1= input.nextDouble();
        x2= input.nextDouble();
        y2= input.nextDouble();
        color= input.next();
        if(!(x1>0&&x1<=200))
        {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        else if(!(x2>0&&x2<=200))
        {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        else if(!(y1>0&&y1<=200))
        {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        else if(!(y2>0&&y2<=200))
        {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        Point point1=new Point(x1,y1);
        Point point2=new Point(x2,y2);
        Line line=new Line(point1,point2,color);
        line.display();
    }
}
class Point
{
    private double x,y;
    public Point()
    {

    }
    public Point(double x,double y)
    {
        this.x = x;
        this.y = y;
    }
    public double getX()
    {
        return x;
    }
    public double getY() {
        return y;
    }
    public void setX(double x) {
        this.x = x;
    }

    public void setY(double y) {
        this.y = y;
    }
    public void display()
    {
        String xx,yy;
        xx=String.format("%.2f",x);
        yy=String.format("%.2f",y);
        System.out.println("("+xx+","+yy+")");
    }
}
class Line
{
    private Point point1;
    private Point point2;
    private String color;
    public Line()
    {

    }
    public Line(Point point1,Point point2,String color)
    {
        this.point1=point1;
        this.point2=point2;
        this.color=color;
    }

    public Point getPoint1() {
        return point1;
    }

    public Point getPoint2() {
        return point2;
    }

    public String getColor() {
        return color;
    }

    public void setPoint1(Point point1) {
        this.point1 = point1;
    }

    public void setPoint2(Point point2) {
        this.point2 = point2;
    }

    public void setColor(String color) {
        this.color = color;
    }
    public double getDistance()
    {
        double dis;
        dis=Math.sqrt((point1.getX()- point2.getX())*(point1.getX()- point2.getX())+(point1.getY()- point2.getY())*(point1.getY()- point2.getY()));
        return dis;
    }
    public void display()
    {
        System.out.println("The line's color is:"+this.color);
        System.out.println("The line's begin point's Coordinate is:");
        point1.display();
        System.out.println("The line's end point's Coordinate is:");
        point2.display();
        String dis;
        dis=String.format("%.2f",getDistance());
        System.out.print("The line's length is:"+dis);
    }
}

类图:
img

SourceMonitor生成的报表内容:
img

本题心得:
按照题目给出的类图进行设计即可,比较清晰方便,关于输入值的判断没有写在Point类里,因为输出的时候出现了多余输出,于是写在了Main函数里。圈复杂度合格,比较满意。

7-2 点线面问题重构(继承与多态)

题目:
在“点与线(类设计)”题目基础上,对题目的类设计进行重构,以实现继承与多态的技术性需求。

  • 对题目中的点Point类和线Line类进行进一步抽象,定义一个两个类的共同父类Element(抽象类),将display()方法在该方法中进行声明(抽象方法),将Point类和Line类作为该类的子类。

  • 再定义一个Element类的子类面Plane,该类只有一个私有属性颜色color,除了构造方法和属性的getter、setter方法外,display()方法用于输出面的颜色,输出格式如下:The Plane's color is:颜色

  • 在主方法内,定义两个Point(线段的起点和终点)对象、一个Line对象和一个Plane对象,依次从键盘输入两个Point对象的起点、终点坐标和颜色值(Line对象和Plane对象颜色相同),然后定义一个Element类的引用,分别使用该引用调用以上四个对象的display()方法,从而实现多态特性。示例代码如下:

    element = p1;//起点Point
    element.display();
      
    element = p2;//终点Point
    element.display();
      
    element = line;//线段
    element.display();
      
    element = plane;//面
    element.display();
    

    类结构如下图所示。
    img

其中,所有数值均保留两位小数,建议可用String.format("%.2f", data)方法。

  • 以下情况为无效作业
    • 无法运行
    • 设计不符合所给类图要求
    • 未通过任何测试点测试
    • 判定为抄袭

输入格式:
分别输入线段的起点横坐标、纵坐标、终点的横坐标、纵坐标以及颜色,中间可用一个或多个空格、tab或者回车分隔。

输出格式:

(x1,y1)
(x2,y2)
The line's color is:颜色值
The line's begin point's Coordinate is:
(x1,y1)
The line's end point's Coordinate is:
(x2,y2)
The line's length is:长度值
The Plane's color is:颜色值

题目分析:
在前题的基础上增加了抽象类,主要考验继承和多态的运用,只需在前面代码的基础上增加共同父类Element(抽象类),并对display()函数分别进行方法重写即可。

源码展示:

import java.util.Scanner;

public class Main
{
    public static void main(String[] args)
    {
        double x1,x2,y1,y2;
        String color;
        Scanner input=new Scanner(System.in);
        x1= input.nextDouble();
        y1= input.nextDouble();
        x2= input.nextDouble();
        y2= input.nextDouble();
        color= input.next();
        if(!(x1>0&&x1<=200))
        {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        else if(!(x2>0&&x2<=200))
        {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        else if(!(y1>0&&y1<=200))
        {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        else if(!(y2>0&&y2<=200))
        {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        Element element;
        Point point1=new Point(x1,y1);
        Point point2=new Point(x2,y2);
        Line line=new Line(point1,point2,color);
        Plane plane=new Plane(color);
        element = point1;//起点Point
        element.display();

        element = point2;//终点Point
        element.display();

        element = line;//线段
        element.display();

        element = plane;//面
        element.display();
    }
}
class Point extends Element
{
    private double x,y;
    public Point()
    {

    }
    public Point(double x,double y)
    {
        this.x = x;
        this.y = y;
    }
    public double getX()
    {
        return x;
    }
    public double getY() {
        return y;
    }
    public void setX(double x) {
        this.x = x;
    }

    public void setY(double y) {
        this.y = y;
    }
    @Override
    public void display()
    {
        String xx,yy;
        xx=String.format("%.2f",x);
        yy=String.format("%.2f",y);
        System.out.println("("+xx+","+yy+")");
    }
}
class Line extends Element
{
    private Point point1;
    private Point point2;
    private String color;
    public Line()
    {

    }
    public Line(Point point1,Point point2,String color)
    {
        this.point1=point1;
        this.point2=point2;
        this.color=color;
    }

    public Point getPoint1() {
        return point1;
    }

    public Point getPoint2() {
        return point2;
    }

    public String getColor() {
        return color;
    }

    public void setPoint1(Point point1) {
        this.point1 = point1;
    }

    public void setPoint2(Point point2) {
        this.point2 = point2;
    }

    public void setColor(String color) {
        this.color = color;
    }
    public double getDistance()
    {
        double dis;
        dis=Math.sqrt((point1.getX()- point2.getX())*(point1.getX()- point2.getX())+(point1.getY()- point2.getY())*(point1.getY()- point2.getY()));
        return dis;
    }
    @Override
    public void display()
    {
        System.out.println("The line's color is:"+this.color);
        System.out.println("The line's begin point's Coordinate is:");
        point1.display();
        System.out.println("The line's end point's Coordinate is:");
        point2.display();
        String dis;
        dis=String.format("%.2f",getDistance());
        System.out.println("The line's length is:"+dis);
    }
}
class Plane extends Element
{
    private String color;
    public Plane()
    {

    }
    public Plane(String color)
    {
        this.color = color;
    }
    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public void display()
    {
        System.out.println("The Plane's color is:"+color);
    }
}
abstract class Element
{
    abstract public void display();
}

类图:
img

SourceMonitor生成的报表内容:
img

本题心得:
只要清楚了抽象类、继承的运用,那么此题就会变得十分简单,代码量也会减少许多。所以理解很重要。

7-3 点线面问题再重构(容器类)

题目:
在“点与线(继承与多态)”题目基础上,对题目的类设计进行重构,增加容器类保存点、线、面对象,并对该容器进行相应增、删、遍历操作。

  • 在原有类设计的基础上,增加一个GeometryObject容器类,其属性为ArrayList< Element >类型的对象(若不了解泛型,可以不使用< Element >)

  • 增加该类的add()方法及remove(int index)方法,其功能分别为向容器中增加对象及删除第index - 1(ArrayList中index>=0)个对象

  • 在主方法中,用户循环输入要进行的操作(choice∈[0,4]),其含义如下:

    • 1:向容器中增加Point对象

    • 2:向容器中增加Line对象

    • 3:向容器中增加Plane对象

    • 4:删除容器中第index - 1个数据,若index数据非法,则无视此操作

    • 0:输入结束
      示例代码如下:

      choice = input.nextInt();
      while(choice != 0) {
          switch(choice) {
          case 1://insert Point object into list 
            ...
              break;
          case 2://insert Line object into list
              ...
              break;
          case 3://insert Plane object into list
              ...
              break;
          case 4://delete index - 1 object from list
              int index = input.nextInt();
              ...
          }
          choice = input.nextInt();
      }
      

      输入结束后,按容器中的对象顺序分别调用每个对象的display()方法进行输出。
      类图如下所示:
      img

  • 以下情况为无效作业

    • 无法运行
    • 设计不符合所给类图要求
    • 未通过任何测试点测试
    • 判定为抄袭

输入格式:

switch(choice) {
            case 1://insert Point object into list 
              输入“点”对象的x,y值
                break;
            case 2://insert Line object into list
                输入“线”对象两个端点的x,y值
                break;
            case 3://insert Plane object into list
                输入“面”对象的颜色值
                break;
            case 4://delete index - 1 object from list
                输入要删除的对象位置(从1开始)
                ...
            }

输出格式:

  • Point、Line、Plane的输出参考题目2
  • 删除对象时,若输入的index超出合法范围,程序自动忽略该操作

题目分析:
此题重点在于Arraylist类的运用,题目所给出的点、线、面都可以以Element类型存入Arraylist这一容器当中。需要注意的一点是Remove函数题目要求删除的是index-1位置的元素,并且防止index超出合法范围。

源码展示:

import java.util.ArrayList;
import java.util.Scanner;

public class Main
{
    public static void main(String[] args)
    {
        double x,y,x1,x2,y1,y2;
        int choice;
        String color;
        GeometryObject geometryObject=new GeometryObject();
        Scanner input=new Scanner(System.in);
        choice = input.nextInt();
        while(choice != 0) {
            switch(choice) {
                case 1:
                    x= input.nextDouble();
                    y= input.nextDouble();
                    if(!(x>0&&x<=200))
                    {
                        System.out.println("Wrong Format");
                        System.exit(0);
                    }
                    else if(!(y>0&&y<=200))
                    {
                        System.out.println("Wrong Format");
                        System.exit(0);
                    }
                    Point point=new Point(x,y);
                    geometryObject.add(point);
                    break;
                case 2:
                    x1= input.nextDouble();
                    y1= input.nextDouble();
                    x2= input.nextDouble();
                    y2= input.nextDouble();
                    color= input.next();
                    if(!(x1>0&&x1<=200))
                    {
                        System.out.println("Wrong Format");
                        System.exit(0);
                    }
                    else if(!(x2>0&&x2<=200))
                    {
                        System.out.println("Wrong Format");
                        System.exit(0);
                    }
                    else if(!(y1>0&&y1<=200))
                    {
                        System.out.println("Wrong Format");
                        System.exit(0);
                    }
                    else if(!(y2>0&&y2<=200))
                    {
                        System.out.println("Wrong Format");
                        System.exit(0);
                    }
                    Point point1=new Point(x1,y1);
                    Point point2=new Point(x2,y2);
                    Line line=new Line(point1,point2,color);
                    geometryObject.add(line);
                    break;
                case 3://insert Plane object into list
                    color= input.next();
                    Plane plane=new Plane(color);
                    geometryObject.add(plane);
                    break;
                case 4://delete index - 1 object from list
                    int index = input.nextInt();
                    geometryObject.remove(index);
            }
            choice = input.nextInt();
        }
        ArrayList<Element> list=geometryObject.getList();
        for(Element i:list)
            i.display();
    }
}
class Point extends Element
{
    private double x,y;
    public Point()
    {

    }
    public Point(double x,double y)
    {
        this.x = x;
        this.y = y;
    }
    public double getX()
    {
        return x;
    }
    public double getY() {
        return y;
    }
    public void setX(double x) {
        this.x = x;
    }

    public void setY(double y) {
        this.y = y;
    }
    @Override
    public void display()
    {
        String xx,yy;
        xx=String.format("%.2f",x);
        yy=String.format("%.2f",y);
        System.out.println("("+xx+","+yy+")");
    }
}
class Line extends Element
{
    private Point point1;
    private Point point2;
    private String color;
    public Line()
    {

    }
    public Line(Point point1,Point point2,String color)
    {
        this.point1=point1;
        this.point2=point2;
        this.color=color;
    }

    public Point getPoint1() {
        return point1;
    }

    public Point getPoint2() {
        return point2;
    }

    public String getColor() {
        return color;
    }

    public void setPoint1(Point point1) {
        this.point1 = point1;
    }

    public void setPoint2(Point point2) {
        this.point2 = point2;
    }

    public void setColor(String color) {
        this.color = color;
    }
    public double getDistance()
    {
        double dis;
        dis=Math.sqrt((point1.getX()- point2.getX())*(point1.getX()- point2.getX())+(point1.getY()- point2.getY())*(point1.getY()- point2.getY()));
        return dis;
    }
    @Override
    public void display()
    {
        System.out.println("The line's color is:"+this.color);
        System.out.println("The line's begin point's Coordinate is:");
        point1.display();
        System.out.println("The line's end point's Coordinate is:");
        point2.display();
        String dis;
        dis=String.format("%.2f",getDistance());
        System.out.println("The line's length is:"+dis);
    }
}
class Plane extends Element
{
    private String color;
    public Plane()
    {

    }
    public Plane(String color)
    {
        this.color = color;
    }
    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public void display()
    {
        System.out.println("The Plane's color is:"+color);
    }
}
abstract class Element
{
    abstract public void display();
}
class GeometryObject
{
    ArrayList<Element> list=new ArrayList<>();
    public GeometryObject()
    {

    }
    public void add(Element element)
    {
        list.add(element);
    }
    public void remove(int index)
    {
        if(index> list.size())
            return;
        list.remove(index-1);
    }
    public ArrayList<Element> getList() {
        return list;
    }
}

类图:
img

SourceMonitor生成的报表内容:
img

本题心得:
本题的代码在主函数的复杂度过大,也许是因为在主函数关于输入点的坐标值是否符合范围的判断过多,比较冗余化,因此需要优化一下错误判断。

3.采坑心得

① 点线形系列4-凸四边形的计算

在选项2中,需要先判断是否构成四边形,再判断是否点重合,否则会输出错误过不去测试点,这一点卡了我很久,直到检查测试样例的时候才发现还有这么一个优先级,算是一个大坑了。

② 点线形系列5-凸五边形的计算-1

在此题中冗余点的删除十分重要,特别是多点共线时删除中间的冗余点,此时需要循环删除:
img
同时在五边形的判断中,点的输出顺序也比四边形判断要更复杂,考虑的不仅是两条对角线,还需要看相邻线段是否非共线,不相邻线段是否非相交:
img

③ 点线形系列5-凸五边形的计算-2

在判断两多边形的连接情况时,还需要考虑是否有两条直线共线,如果不考虑线只考虑到点的话,会在判断交错情况时出现误判。
img
另外求交错的公共区域面积时,获取的所有坐标点存储起来时,需要进行排序,否则乱序的坐标点无法构成多边形,更不可能求出正确的面积,于是需要用到向量的叉积:
img
根据此点进行冒泡排序即可。

4.改进建议

题目集4与题目集5的代码可能需要再次重构,运用综合多边形抽象类、继承与多态等方法改进代码质量,并用方法重写使得代码的冗余性降低,复用性更高。同时可能需要改进一下算法之类,不能每次都靠暴力解题,使得代码冗长单一。
最后希望老师以后在像多边形这样复杂的题型时,能够给出像期中考试一样的类图样例,这样也能更好地帮助我们设计与构造。

5.总结

通过这几次作业与期中测验,我更认识到了重构的重要性,继承与多态的方便性,类的设计和方法构造能力也得到了提升,但是对各种测试点的坑还是心有余悸,因为有时候你不知道是什么原因导致你错误,哪怕测试样例正常,自己给出的样例全通,还是要不断地检查与重试。也希望以后的代码质量能够越来越高吧,稳步向前。

posted @   昌航小迷弟六号  阅读(365)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示