哈哈的第二次BLOG作业

(1)前言:

第四次作业有三题,第一题和第三题比较简单,主要考察怎么定义类以及如何使用类中方法和属性。第二题较难,难在如何将数学语言转化为Java语言,难在算法,虽然我不知道这能否称之为算法。

期中考试也有三题,题目应该不算难,但是我并未在规定时间完成,主要考察类的设计,继承与多态,还有容器类的设计。

第五次作业有两题,严格来讲是一题,我认为有点难,具体分析在下面讲吧。

 

(2)设计与分析:

首先就是第四次大作业的第二题:

用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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"。

输入样例1:

选项1,点重合。例如:

1:-1,-1 -1,-1 1,2 1,-2
 

输出样例:

在这里给出相应的输出。例如:

points coincide
 

输入样例2:

不符合基本格式。例如:

1:-1,-1 1,2 -1,1 ++1,0
 

输出样例:

在这里给出相应的输出。例如:

Wrong Format
 

输入样例3:

选项1,输入点数量不对。例如:

1:-1,-1 -1,2 
 

输出样例:

在这里给出相应的输出。例如:

wrong number of points
 

输入样例4:

选项1,正确输入判断。例如:

1:-1,-1 -1,1 1,2 1,-2
 

输出样例:

在这里给出相应的输出。例如:

true false
 

输入样例5:

选项2,输入点不构成四边形。例如:

2:10,10 1,1 0,0 1,20
 

输出样例:

在这里给出相应的输出。例如:

not a quadrilateral
 

输入样例6:

选项2,正方形。例如:

2:0,0 0,80 80,80 80,0
 

输出样例:

在这里给出相应的输出。例如:

true true true
 

输入样例7:

选项2。例如:

2:0,0 -10,80 0,160 -10,80
 

输出样例:

在这里给出相应的输出。例如:

not a quadrilateral
 

输入样例8:

选项3,凸四边形。例如:

3:-1,-1 -1,1 1,2 1,-2
 

输出样例:

在这里给出相应的输出。例如:

true 10.472 6.0
 

输入样例9:

选项3,。例如:

3:0,0 -10,100 0,99 10,100
 

输出样例:

在这里给出相应的输出。例如:

false 221.097 990.0
源码如下,点加号展开
复制代码
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        String str = in.nextLine();
        if(legal(str))
        {
            int a = str.charAt(0)-'0';
            Point[] p = change(str);
//            Sibian A = new Sibian(p);
            switch(a) 
            {
            case 1:
                if(count(str)!=4)
                {
                    System.out.println("wrong number of points");
                }
                else
                {
                    Sibian A = new Sibian(p);
                    if(isCopy(p)==false) {
                        System.out.println("points coincide");
                    }
                    else {
                        System.out.println(A.isQuadrangle()+" "+A.isRhomboid());
                    }
                }
                break;
            case 2:
                if(count(str)!=4)
                {
                    System.out.println("wrong number of points");
                }
                else
                {
                    Sibian A = new Sibian(p);
                    if(isCopy(p)==false) {
                        System.out.println("points coincide");
                    }
                    else {
                        if(A.isQuadrangle()==true){
                            System.out.println(A.isRhombus()+" "+A.isRectangle()+" "+A.isSquare());
                        }
                        else {
                            System.out.println("not a quadrilateral");
                        }
                    }
                }
                break;
            case 3:
                if(count(str)!=4)
                {
                    System.out.println("wrong number of points");
                }
                break;
            case 4:
                if(count(str)!=6)
                {
                    System.out.println("wrong number of points");
                }
                break;
            }
            
        }
        else
        {
            System.out.println("Wrong Format");
        }
        
    }
    
    
    //判断输入是否合法
    public static boolean legal(String str)
    {
        boolean a = true;
        int b = 0;
        if('0'<str.charAt(0)&&str.charAt(0)<'9'&&str.charAt(1)==':')
        {
            String[] s = str.split(":");
            String[] s1 = s[1].split(" ");
            for(int i = 0;i<s1.length;i++)
            {
                if(!s1[i].matches("^[+-]?(0|[1-9][\\\\\\\\d]{0,})(\\\\\\\\.[\\\\\\\\d]{1,})?[\\\\\\\\,][+-]?(0|[1-9][\\\\\\\\d]{0,})(\\\\\\\\.[\\\\\\\\d]{1,})?"))
                {
                    b++;    
                }
            }
            if(b==0)
            {
                a = true;
            }
            else
            {
                a = false;
            }
        }
        else
        {
            a = false;
        }
        return a;
    }
    
    
    //计算输入点个数  根据,数量计算
    public static int count(String str)
    {
        int a = 0;
        for(int i = 0;i<str.length();i++)
        {
            if(str.charAt(i) == ',')
                 a++;

        }
        return a;
    }
    public static Point[] change(String str)//获取点数据
    {
        
        String[] s = str.split(":");
        String[] s1 = s[1].split(" ");
        Point[] p = new Point[s1.length];
        for(int i = 0;i<s1.length;i++) {
            int num = s1[i].indexOf(",");
            double m,n;
            m = Double.parseDouble(s1[i].substring(0,num));
            n = Double.parseDouble(s1[i].substring(num+1,s1[i].length()));
            p[i] = new Point(m,n);
        }
        return p;
    }
    
    //判断是否有重合点,返回true表示没有重合点
    public static boolean isCopy(Point[] p) {
        int a =0 ;
        boolean b = true;
        for(int i = 0;i<p.length;i++) {
            for(int j = i+1;j<p.length;j++) {
                if(p[i].getX()==p[j].getX()&&p[i].getY()==p[j].getY()) {
                    a++;
                }
            }
        }
        if(a==0) {
            b = true;
        }
        else {
            b = false;
        }
        return b;
    }

}
 class Point {
    private double x;
    private double y;
    public Point(double x,double y){
        this.x=x;
        this.y=y;       
    }
    public double getX() {
        return x;
    }
    public void setX(double x) {
        this.x = x;
    }
    public double getY() {
        return y;
    }
    public void setY(double y) {
        this.y = y;
    }
    public double getDistance(Point p1,Point p2) {
        double distance = Math.sqrt((p1.x-p2.x)*(p1.x-p2.x)+
                (p1.y-p2.y)*(p1.y-p2.y));
        return distance;
    }
}
 class Line {
    private Point p1,p2 ;
    private double slope; //斜率
 
    public double getSlope() {
        return slope;
    }
 
    public void setSlope(double slope) {
        this.slope = slope;
    }
 
    public boolean isParallel(Line line) { //比较两个斜率是否相同
        if(this.slope==line.slope) {
            return true;
        }
        else {
            return false;
        }
    }
    public Line(Point p1,Point p2){
        this.p1 = p1;
        this.p2 = p2;
        if(p1.getX()!=p2.getX()) {
            this.slope = (p1.getY()-p2.getY())/(p1.getX()-p2.getX());
        }
        else {
            this.slope = 100000;
        }
    }
 }
   class Sibian{
       private Line[] line = new Line[4];
       private Point[] p1 = new Point[4];
       Sibian(Point[] p) {
           line[0] = new Line(p[0],p[1]);
           line[1] = new Line(p[1],p[2]);
           line[2] = new Line(p[2],p[3]);
           line[3] = new Line(p[3],p[0]);
           p1 = p;
       }
       
       //判断是否为四边形
   public boolean isQuadrangle() {
       boolean a = true;
       if(line[0].getSlope()!=line[1].getSlope()
               &&line[1].getSlope()!=line[2].getSlope()
               &&line[2].getSlope()!=line[3].getSlope()
               &&line[3].getSlope()!=line[0].getSlope()){
           a = true;
       }
       else{
           a = false;
       }
       return a;
   }  
   
   //判断是否为平行四边形
       public boolean isRhomboid() {
           boolean a = true;
           if(this.isQuadrangle()&&line[0].getSlope()==line[2].getSlope()&&line[1].getSlope()==line[3].getSlope()) {
               a = true;
           }
           else {
               a = false;
           }
           return a;
       }
       
       
       //判断是否为菱形
       public boolean isRhombus() {
           boolean a = true;
           if(this.isRhomboid()==true&&p1[1].getDistance(p1[0],p1[1])==p1[1].getDistance(p1[1],p1[2])
                   &&p1[1].getDistance(p1[1],p1[2])==p1[1].getDistance(p1[2],p1[3])
                   &&p1[1].getDistance(p1[2],p1[3])==p1[1].getDistance(p1[3],p1[0])) {
               a = true;
           }
           else {
               a = false;
           }
           return a;
       }
       
       
       //判断是否为矩形
       public boolean isRectangle() {
           boolean a = true;
           if(p1[0].getX()==p1[3].getX()&&p1[1].getX()==p1[2].getX()&&p1[0].getY()==p1[1].getY()&&p1[2].getY()==p1[3].getY()) {
               a = true;
           }
           else {
               a = false;
           }
           return a;
       }
       
       
       //判断是否为正方形
       public boolean isSquare() {
           boolean a = true;
           if(this.isRhombus()==true&&this.isRectangle()==true) {
               a = true;
           }
           else {
               a = false;
           }
           return a;
       }
}
View Code
复制代码

首先这题难在输入格式的判断,其次就涉及到题目自身问题的算法上,怎么判断是否为正方形,是否为菱形之类的,真的好难。这里我附上我的类图

 

 

 这个说实话设计的简单,可能这就是我拿不了高分的原因,没什么参考意义。

接着看期中考试的题目吧:

  • 设计一个类表示平面直角坐标系上的点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)方法。

      设计类图如下图所示。
  •  

     

    * 题目要求:在主方法中定义一条线段对象,从键盘输入该线段的起点坐标与终点坐标以及颜色,然后调用该线段的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:长度值
    
     

    输入样例1:

    在这里给出一组输入。例如:

    5
    9.4
    12.3
    84
    Red
    
     

    输出样例1:

    在这里给出相应的输出。例如:

    The line's color is:Red
    The line's begin point's Coordinate is:
    (5.00,9.40)
    The line's end point's Coordinate is:
    (12.30,84.00)
    The line's length is:74.96
    
     

    输入样例2:

    在这里给出一组输入。例如:

    80.2356
    352.12
    24.5
    100
    Black
    
     

    输出样例2:

    在这里给出相应的输出。例如:

    Wrong Format
这个题目已经给出了类图,只要照着写就行了,附上源码
复制代码
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        String[] strs = new String[5];
        for(int i = 0;i<5;i++) {
             strs[i] = in.nextLine();
        }
        int a = 0;
        for(int i = 0;i<4;i++) {
            if(!(Double.parseDouble(strs[i].substring(0,strs[i].length()))>0&&Double.parseDouble(strs[i].substring(0,strs[i].length()))<200)) {
                a++;
            }
        }
        if(a==0) {
            Point p1 = new Point(Double.parseDouble(strs[0].substring(0,strs[0].length())),Double.parseDouble(strs[1].substring(0,strs[1].length())));
            Point p2 = new Point(Double.parseDouble(strs[2].substring(0,strs[2].length())),Double.parseDouble(strs[3].substring(0,strs[3].length())));
            Line line = new Line(p1,p2,strs[4]);
            line.display();
        }
        else {
            System.out.println("Wrong Format");
        }
    }

}

class Point {
    private double x;
    private double y;
    public double getX() {
        return x;
    }
    public double getY() {
        return y;
    }
    public void setX(double a) {
        this.x = a;
    }
    public void setY(int a) {
        this.y = a;
    }
    public void display() {
        System.out.println("("+String.format("%.2f", x)+","+String.format("%.2f", y)+")");
    }
    Point(){
        
    }
    Point(double x,double y){
        this.x = x;
        this.y = y;
        
    }
}
class Line{
    private Point Point1;
    private Point Point2;
    private String color;
    Line(){
        
    }
    Line(Point Point1,Point Point2,String color){
        this.Point1 = Point1;
        this.Point2 = Point2;
        this.color = color;
    }
    public Point getPoint1() {
        return Point1;
    }
    public void setPoint1(Point Point1) {
        this.Point1 = Point1;
    }
    public Point getPoint2() {
        return Point2;
    }
    public void setPoint2(Point Point2) {
        this.Point2 = Point2;
    }
    public String getColor(){
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public double getDistance() {
        double distance = Math.sqrt((Point1.getX()-Point2.getX())*(Point1.getX()-Point2.getX())+
                (Point1.getY()-Point2.getY())*(Point1.getY()-Point2.getY()));
        return distance;
        
    }
    public void display() {
        System.out.println("The line's color is:"+color);
        System.out.println("The line's begin point's Coordinate is:");
        System.out.println("("+String.format("%.2f", Point1.getX())+","+String.format("%.2f", Point1.getY())+")");
        System.out.println("The line's end point's Coordinate is:");
        System.out.println("("+String.format("%.2f", Point2.getX())+","+String.format("%.2f", Point2.getY())+")");
        System.out.println("The line's length is:"+String.format("%.2f", this.getDistance()));
    }
}
View Code
复制代码

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

  • 对题目中的点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();
  •  

     这题就是在第一题的基础上合理利用继承与多态,附上源码

  • 复制代码
    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner in = new Scanner(System.in);
            String[] strs = new String[5];
            for(int i = 0;i<5;i++) {
                 strs[i] = in.nextLine();
            }
            int a = 0;
            for(int i = 0;i<4;i++) {
                if(!(Double.parseDouble(strs[i].substring(0,strs[i].length()))>0&&Double.parseDouble(strs[i].substring(0,strs[i].length()))<200)) {
                    a++;
                }
            }
            if(a==0) {
                Point p1 = new Point(Double.parseDouble(strs[0].substring(0,strs[0].length())),Double.parseDouble(strs[1].substring(0,strs[1].length())));
                Point p2 = new Point(Double.parseDouble(strs[2].substring(0,strs[2].length())),Double.parseDouble(strs[3].substring(0,strs[3].length())));
                Line line = new Line(p1,p2,strs[4]);
                Plane plane;
                Element element;
                  element = p1;//起点Point
                  element.display();
                  
                  element = p2;//终点Point
                  element.display();
                  
                  element = line;//线段
                  element.display();
                  
                  element = plane;//
                  element.display();
    
                line.display();
            }
            else {
                System.out.println("Wrong Format");
            }
        }
    
    }
    
    class Point extends Element {
        private double x;
        private double y;
        public double getX() {
            return x;
        }
        public double getY() {
            return y;
        }
        public void setX(double a) {
            this.x = a;
        }
        public void setY(int a) {
            this.y = a;
        }
        public void display() {
            System.out.println("("+String.format("%.2f", x)+","+String.format("%.2f", y)+")");
        }
        Point(){
            
        }
        Point(double x,double y){
            this.x = x;
            this.y = y;
            
        }
    }
    class Line extends Element{
        private Point Point1;
        private Point Point2;
        private String color;
        Line(){
            
        }
        Line(Point Point1,Point Point2,String color){
            this.Point1 = Point1;
            this.Point2 = Point2;
            this.color = color;
        }
        public Point getPoint1() {
            return Point1;
        }
        public void setPoint1(Point Point1) {
            this.Point1 = Point1;
        }
        public Point getPoint2() {
            return Point2;
        }
        public void setPoint2(Point Point2) {
            this.Point2 = Point2;
        }
        public String getColor(){
            return color;
        }
        public void setColor(String color) {
            this.color = color;
        }
        public double getDistance() {
            double distance = Math.sqrt((Point1.getX()-Point2.getX())*(Point1.getX()-Point2.getX())+
                    (Point1.getY()-Point2.getY())*(Point1.getY()-Point2.getY()));
            return distance;
            
        }
        public void display() {
            System.out.println("The line's color is:"+color);
            System.out.println("The line's begin point's Coordinate is:");
            System.out.println("("+String.format("%.2f", Point1.getX())+","+String.format("%.2f", Point1.getY())+")");
            System.out.println("The line's end point's Coordinate is:");
            System.out.println("("+String.format("%.2f", Point2.getX())+","+String.format("%.2f", Point2.getY())+")");
            System.out.println("The line's length is:"+String.format("%.2f", this.getDistance()));
        }
    }
    abstract class Element{
        abstract void display();
    }
    class Plane extends Element{
        private String color;
        Plane(){
        }
        Plane(String color){
            this.color = color;
        }
        public String getColor() {
            
            return color;
        }
        public void setColor(String color) {
            this.color = color;
        }
        public void display() {
            System.out.println("The Plane's color is:"+color);
        }
    }
    View Code
    复制代码

    然后就是第五次作业,因为有了前几次图形类的设计这一次看起来更简单,但其实它的测试点还是不好过

  • 题目如下:

    用户输入一组选项和数据,进行与五边形有关的计算。
    以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
    选项包括:
    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

    输入样例1:

    选项1,点重合。例如:

    1:-1,-1 1,2 -1,1 1,0
    
     

    输出样例:

    在这里给出相应的输出。例如:

    wrong number of points
  • 
    

    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

    输入样例:

    在这里给出一组输入。例如:

    4:0,0 6,0 7,1 8,3 6,6 0,0 6,0 7,1 8,3 6,6
    
     

    输出样例:

    在这里给出相应的输出。例如:

    the previous pentagon coincides with the following pentagon
  • 源码
  • 复制代码
    import java.text.DecimalFormat;
    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner in = new Scanner(System.in);
            String str = in.nextLine();
            if(legal(str))
            {
                int a = str.charAt(0)-'0';
                Point[] p = change(str);
    
                switch(a) 
                {
                case 1:
                    if(count(str)!=5)
                    {
                        System.out.println("wrong number of points");
                    }
                    else
                    {
                        Wubian A = new Wubian(p);
                            System.out.println(A.isPentagon());
                        
                    }
                    break;
                case 2:
                    if(count(str)!=5)
                    {
                        System.out.println("wrong number of points");
                    }
                    else
                    {
                        Wubian A = new Wubian(p);
                        
                        
                            if(A.isPentagon()){
                                if(A.Concave_Convex()) {
                                    System.out.println(true+" "+A.getPerimeter()+" "+A.getArea());
                                }
                                else
                                    System.out.println(false);
                            }
                            else {
                                System.out.println("not a pentagon");
                            }
                        
                    }
                    break;
                case 3:
                    if(count(str)!=7) {
                        System.out.println("wrong number of points");
                    }
                    else {
                        Line[] line = new Line[5];
                        Point[] p1 = new Point[]{p[0],p[1]};
                        Point[] p2 = new Point[]{p[2],p[3],p[4],p[5],p[6]};
                        line[0] = new Line(p2[0],p2[1]);
                       line[1] = new Line(p2[1],p2[2]);
                       line[2] = new Line(p2[2],p2[3]);
                       line[3] = new Line(p2[3],p2[4]);
                       line[4] = new Line(p2[4],p2[0]);
                        if(isCopy(p1)) {
                            Line line1 = new Line(p1[0],p1[1]);
                            Wubian A = new Wubian(p2);
                            if(isCopy(p2)&&A.isPentagon()) {//表示无重合点,构成五边形
                                
                                if(isCoincide(line1,A.getLine())) {
                                    System.out.println(getCrosspoint(line1,A.getLine()));
                                }
                                else {
                                    System.out.println("The line is coincide with one of the lines");
                                }
                            }
                            
                            if(getOnline(p2,line)==12) {//构成四边形
                                
                            }
                            if(getOnline(p2,line)>12) {//构成三角形
                                
                            }
                            
                        }
                        else {
                            System.out.println("points coincide");
                        }
                    }
                    break;
                case 4:
                    if(count(str)!=10)
                    {
                        System.out.println("wrong number of points");
                    }
                    else
                        System.out.println("the previous pentagon coincides with the following pentagon");
                    break;
                }
                
            }
            else
            {
                System.out.println("Wrong Format");
            }
            
         }
        
        
        //判断输入是否合法
        public static boolean legal(String str)
        {
            boolean a = true;
            int b = 0;
            if('0'<str.charAt(0)&&str.charAt(0)<'9'&&str.charAt(1)==':')
            {
                String[] s = str.split(":");
                String[] s1 = s[1].split(" ");
                for(int i = 0;i<s1.length;i++)
                {
                    if(!s1[i].matches("^[+-]?(0|[1-9][\\d]*)(\\.[\\d]{1,})?[\\,][+-]?(0|[1-9][\\d]{0,})(\\.[\\d]{1,})?"))
                    {
                        b++;    
                    }
                }
                if(b==0)
                {
                    a = true;
                }
                else
                {
                    a = false;
                }
            }
            else
            {
                a = false;
            }
            return a;
        }
        
        
        //计算输入点个数  根据,数量计算
        public static int count(String str)
        {
            int a = 0;
            for(int i = 0;i<str.length();i++)
            {
                if(str.charAt(i) == ',')
                     a++;
    
            }
            return a;
        }
        public static Point[] change(String str)//获取点数据
        {
            
            String[] s = str.split(":");
            String[] s1 = s[1].split(" ");
            Point[] p = new Point[s1.length];
            for(int i = 0;i<s1.length;i++) {
                int num = s1[i].indexOf(",");
                double m,n;
                m = Double.parseDouble(s1[i].substring(0,num));
                n = Double.parseDouble(s1[i].substring(num+1,s1[i].length()));
                p[i] = new Point(m,n);
            }
            return p;
        }
        
        //判断是否有重合点,返回true表示没有重合点
        public static boolean isCopy(Point[] p) {
            int a =0 ;
            boolean b = true;
            for(int i = 0;i<p.length;i++) {
                for(int j = i+1;j<p.length;j++) {
                    if(p[i].getX()==p[j].getX()&&p[i].getY()==p[j].getY()) {
                        a++;
                    }
                }
            }
            if(a==0) {
                b = true;
            }
            else {
                b = false;
            }
            return b;
        }
        
        //获取重合点个数
        public static int getCopy(Point[] p) {
            int a = 0;
            for(int i = 0;i<p.length;i++) {
                for(int j = i+1;j<p.length;j++) {
                    if(p[i].getX()==p[j].getX()&&p[i].getY()==p[j].getY()) {
                        a++;
                    }
                }
            }
            return a;
        }
        
        //判断线是否与多边形边重合,true表示无重合
        public static boolean isCoincide(Line line,Line[] line1) {
            int a = 0;
            for(int i = 0;i<line1.length;i++) {
                if(line.isCoincide(line1[i])) {
                    a++;
                }
            }
            if(a==0) {
                return true;
            }
            else
                return false;
        }
        
        //获取直线与多边形交点个数
        public static int getCrosspoint(Line line,Line[] line1) {
            int a = 0;
            for(int i = 0;i<line1.length;i++) {
                if(line.isCrosspoint_1(line1[i])) {
                    a++;
                }
            }
            return a;
        }
        
        //点在线上的个数
        public static int getOnline(Point[] p,Line[] line) {
            int a = 0;
              for(int i = 0;i<5;i++) {
                   for(int j = 0;j<5;j++) {
                       if(line[j].isOnline(p[i])) {
                           a++;
                       }
                   }
               }
              return a;
        }
    
    }
     class Point {
        private double x;
        private double y;
        public Point(double x,double y){
            this.x=x;
            this.y=y;       
        }
        public double getX() {
            return x;
        }
        public void setX(double x) {
            this.x = x;
        }
        public double getY() {
            return y;
        }
        public void setY(double y) {
            this.y = y;
        }
        public double getDistance(Point p1,Point p2) {
            double distance = Math.sqrt((p1.x-p2.x)*(p1.x-p2.x)+
                    (p1.y-p2.y)*(p1.y-p2.y));
            return distance;
        }
    }
     class Line {
        private Point p1,p2 ;
        private double slope; //斜率
     
        public double getSlope() {
            return slope;
        }
     
        public void setSlope(double slope) {
            this.slope = slope;
        }
     
        //比较两个斜率是否相同
        public boolean isParallel(Line line) { 
            if(this.slope==line.slope) {
                return true;
            }
            else {
                return false;
            }
        }
        
        //判断两线是否重合
        public boolean isCoincide(Line line) {
            if (!this.isParallel(line)) {
                return false;
            }
            else {
                if(this.isOnline(line.p1)){
                    return true;
                }
                else
                    return false;
            }
        }
        
        //判断点是否在线上
        public boolean isOnline(Point x) {
            Line line = new Line(this.p1,x);
            if(line.getSlope()==this.slope) {
                return true;
            }
            else
                return false;
        }
        
        //两点之间距离
         public double getDistance1() {
                double distance = Math.sqrt((p1.getX()-p2.getX())*(p1.getX()-p2.getX())+
                        (p1.getY()-p2.getY())*(p1.getY()-p2.getY()));
                return distance;
            }
         
         //点到直线的距离
        public double getDistance(Point p) {
            double result;
            result = (-this.slope*p.getX()+p.getY()+this.slope*this.p1.getX()-this.p1.getY())/Math.sqrt(this.slope*this.slope-1);
            return result;
        }
        
        //判断直线与线段是否有交点,传入line的为线段
        public boolean isCrosspoint_1(Line line){
            double x = 0,y = 0;
            if(this.slope!=line.getSlope()) {
                if(this.p1.getX()==this.p2.getX()||line.p1.getX()==line.p2.getX()) {
                    if(this.p1.getX()==this.p2.getX()) {
                        x = this.p1.getX();
                        y = line.getSlope()*x+line.getSlope()*line.p1.getX()-line.p1.getY();
                    }
                    else if(line.p1.getX()==line.p2.getX()) {
                        x = line.p1.getX();
                        y = this.getSlope()*x+this.getSlope()*p1.getX()-p1.getY();
                    }
                    
                }
                else {
                    x = -((line.getSlope()*line.p1.getX()-line.p1.getY())-(this.slope*p1.getX()-p1.getY()))/(this.slope-line.getSlope());
                    y = -(x*this.getSlope()+this.getSlope()*p1.getX()-p1.getY());
                }
                if(((x>line.p1.getX()||Math.abs(x-line.p1.getX())<1e-6)&&(x<line.p2.getX()||Math.abs(x-line.p2.getX())<1e-6)
                    ||(x<line.p1.getX()||Math.abs(x-line.p1.getX())<1e-6)&&(x>line.p2.getX()||Math.abs(x-line.p2.getX())<1e-6))) {
                    return true;
                }
                else
                    return false;
            }
            else
                return false;
        }
        
        
        
        //判断两线段是否有交点
        public boolean isCrosspoint(Line line) {
            double x = 0,y = 0;
            if(this.slope!=line.getSlope()) {
                if(this.p1.getX()==this.p2.getX()||line.p1.getX()==line.p2.getX()) {
                    if(this.p1.getX()==this.p2.getX()) {
                        x = this.p1.getX();
                        y = line.getSlope()*x+line.getSlope()*line.p1.getX()-line.p1.getY();
                    }
                    else if(line.p1.getX()==line.p2.getX()) {
                        x = line.p1.getX();
                        y = this.getSlope()*x+this.getSlope()*p1.getX()-p1.getY();
                    }
                    
                }
                else {
                    x = -((line.getSlope()*line.p1.getX()-line.p1.getY())-(this.slope*p1.getX()-p1.getY()))/(this.slope-line.getSlope());
                    y = -(x*this.getSlope()+this.getSlope()*p1.getX()-p1.getY());
                }
                if(((x>p1.getX()||Math.abs(x-p1.getX())<1e-6)&&(x<p2.getX()||Math.abs(x-p2.getX())<1e-6)
                        ||(x<p1.getX()||Math.abs(x-p1.getX())<1e-6)&&(x>p2.getX()||Math.abs(x-p2.getX())<1e-6))
                        &&((x>line.p1.getX()||Math.abs(x-line.p1.getX())<1e-6)&&(x<line.p2.getX()||Math.abs(x-line.p2.getX())<1e-6)
                        ||(x<line.p1.getX()||Math.abs(x-line.p1.getX())<1e-6)&&(x>line.p2.getX()||Math.abs(x-line.p2.getX())<1e-6))) {
                    return true;
                }
                else
                    return false;
            }
            else
                return false;
        }
        public Line(Point p1,Point p2){
            this.p1 = p1;
            this.p2 = p2;
            if(p1.getX()!=p2.getX()) {
                this.slope = (p1.getY()-p2.getY())/(p1.getX()-p2.getX());
            }
            else {
                this.slope = Double.POSITIVE_INFINITY;
            }
        }
     }
       class Sibian{
           private Line[] line = new Line[4];
           private Point[] p1 = new Point[4];
           Sibian(Point[] p) {
               line[0] = new Line(p[0],p[1]);
               line[1] = new Line(p[1],p[2]);
               line[2] = new Line(p[2],p[3]);
               line[3] = new Line(p[3],p[0]);
               p1 = p;
           }
           
           //判断是否为四边形
       public boolean isQuadrangle() {
           boolean a = true;
           if(line[0].getSlope()!=line[1].getSlope()
                   &&line[1].getSlope()!=line[2].getSlope()
                   &&line[2].getSlope()!=line[3].getSlope()
                   &&line[3].getSlope()!=line[0].getSlope()){
               a = true;
           }
           else{
               a = false;
           }
           return a;
       }  
       
       //判断是否为平行四边形
           public boolean isRhomboid() {
               boolean a = true;
               if(this.isQuadrangle()&&line[0].getSlope()==line[2].getSlope()&&line[1].getSlope()==line[3].getSlope()) {
                   a = true;
               }
               else {
                   a = false;
               }
               return a;
           }
           
           
           //判断是否为菱形
           public boolean isRhombus() {
               boolean a = true;
               if(this.isRhomboid()==true&&p1[1].getDistance(p1[0],p1[1])==p1[1].getDistance(p1[1],p1[2])
                       &&p1[1].getDistance(p1[1],p1[2])==p1[1].getDistance(p1[2],p1[3])
                       &&p1[1].getDistance(p1[2],p1[3])==p1[1].getDistance(p1[3],p1[0])) {
                   a = true;
               }
               else {
                   a = false;
               }
               return a;
           }
           
           
           //判断是否为矩形
           public boolean isRectangle() {
               boolean a = true;
               if(p1[0].getX()==p1[3].getX()&&p1[1].getX()==p1[2].getX()&&p1[0].getY()==p1[1].getY()&&p1[2].getY()==p1[3].getY()) {
                   a = true;
               }
               else {
                   a = false;
               }
               return a;
           }
           
           
           //判断是否为正方形
           public boolean isSquare() {
               boolean a = true;
               if(this.isRhombus()==true&&this.isRectangle()==true) {
                   a = true;
               }
               else {
                   a = false;
               }
               return a;
           }
           
           
           //判断凹凸四边形
    }
    class Wubian{
         private Line[] line = new Line[5];
           private Point[] p1 = new Point[5];
           Wubian(Point[] p) {
               line[0] = new Line(p[0],p[1]);
               line[1] = new Line(p[1],p[2]);
               line[2] = new Line(p[2],p[3]);
               line[3] = new Line(p[3],p[4]);
               line[4] = new Line(p[4],p[0]);
               p1 = p;
           }
           
           //获取Line[]
           public Line[] getLine() {
               return this.line;
           }
           
           //判断是否为五边形
           public boolean isPentagon() {
               int a = 0,b = 0;
    //           for(int i = 0;i<5;i++) {
    //               for(int j = 0;j<5;j++) {
    //                   if(!line[j].isOnline(p1[i])) {
    //                       a++;
    //                   }
    //               }
    //           }
               for(int i = 0;i<5;i++) {
                   for(int j = i+1;j<5;j++) {
                      if(line[i].isCrosspoint(line[j])) {
                          b++;
                      }
                   }
               }
               if(b==5) {
                   return true;
               }
               else
                   return false;
           }
           
           
           //判断凹凸形  根据点到线的距离正负性是否一致判断
           public boolean Concave_Convex() {
               int a = 0;
               for(int i = 0;i<5;i++) {
                   for(int j=0;j<5;j++) {
                      if( line[0].getDistance(p1[j])>0){
                          a++;
                      } 
                   }
               }
               if(a==15||a==0) {
                   return true;
               }
               else
                   return false;
           }
           
           //计算周长
           public String getPerimeter() {
               double result = 0;
               for(int i = 0;i<5;i++) {
                   result =result + line[i].getDistance1();
               }
               return new DecimalFormat("#.###").format(result);
           }
           
           //计算面积  三角形面积计算公式S=1/2[(x1y2-x2y1)+(x2y3-x3y2)+(x3y1-x1y3)]
           public double getArea() {
               double result = 0;
               result = Math.abs(0.5*((p1[0].getX()*p1[1].getY()-p1[1].getX()*p1[0].getY())+(p1[1].getX()*p1[2].getY()-p1[2].getX()*p1[1].getY())
                       +(p1[2].getX()*p1[3].getY()-p1[3].getX()*p1[2].getY())+(p1[3].getX()*p1[4].getY()-p1[4].getX()*p1[3].getY())
                       +(p1[4].getX()*p1[0].getY()-p1[0].getX()*p1[4].getY())));
               return result;
           }
           
    }
    class San{
        
    }
    View Code
    复制代码

(3)采坑心得:

1.有一个值得注意的是double型的0.1实际上打印出来是0.09999999999999998原因就是浮点数是无法精确表示的。所以当我们遇到浮点数运算时,必须要注意这一点。那我们应该怎么解决这个问题呢?当浮点数 |a - b| <(1E-10) ,则认为a与b相等。我就在这里吃过一次亏,希望这次能记住,下次不要再犯错了。

2.判断用户输入是否符合题目要求格式时记得使用正则表达式,这样可以大大提高你代码的效率。

(4)改进建议:对题目的要求一定严格完成,写代码一定要严谨,如判断是否为五边形,一定要找到最严谨的判断方法,然后再转化为Java编程语言,这样才能越写越顺手。

(5)总结:学习情况一般,作业完成情况差一点,希望下次别再出图形类的题目了。

posted @   21201615-李俊  阅读(62)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示