目录
前言
设计与分析
采坑心得
改进建议
总结
(1)前言:总结之前所涉及到的知识点、题量、难度等情况
期中考试的难度是逐渐提高的,但是因为给了类图,难度总的来说比较适中。
第四次的pta作业中第一题和第三题难度比较简单,第二题的难度挺高的,很考验编程能力和对正则表达式的使用。
第五次的pta作业难度是最高的一次作业。
(2)设计与分析:重点对题目的提交源码进行分析,可参考SourceMonitor的生成报表内容以及PowerDesigner的相应类图,要有相应的解释和心得(做到有图有真相),本次Blog必须分析PTA中的图形类设计的题目、超星中链表类练习题目以及期中考试的三道题目
用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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
其余样例,详见附件:
类图:
代码软件分析:
代码主要类:
class Judge { ArrayList<Point> pt = new ArrayList<>(); private int number; public int getIndex() { return number; } public void judge(String s) { int flag =0; String regex = "[1-5]:([+-]?(0|(0\\.[0-9]+)|([1-9][0-9]*(\\.[0-9]+)?)),[+-]?(0|(0\\.[0-9]+)|([1-9][0-9]*(\\.[0-9]+)?))\\s?)+$"; if(s.matches(regex)) { String[] string01 = s.split(":"); number = Integer.parseInt(string01[0]); String[] strings = string01[1].split(" "); for (int i = 0; i < strings.length; i++) { Point pot = new Point(); String[] s1 = strings[i].split(","); pot.setX(Double.parseDouble(s1[0])); pot.setY(Double.parseDouble(s1[1])); pt.add(pot); } } else { System.out.println("Wrong Format"); System.exit(0); } } public boolean number(){ if((pt.size() == 4 && (this.number >= 1 && this.number < 4 )) || (pt.size() == 6 && this.number == 4 ) || (pt.size() == 5 && this.number == 5)) { return true; } else return false; } //判断点是否重合 public boolean coincidence(ArrayList<Point> a) { for (int i = 0; i < a.size(); i+=2) { for (int j = i+1; j < a.size(); j++) { if(a.get(i).getX() == a.get(j).getX() && a.get(i).getY() == a.get(j).getY()) { System.out.println("points coincide"); return false; } } } return true; } //去冗余 public void coincidence2() { if(pt.get(0).chonghe(pt.get(2))) pt.remove(0); else if(pt.get(1).chonghe( pt.get(3))) pt.remove(1); //判断重复的点 for (int i = 0; i < pt.size() - 1; i++) { if(pt.get(i).chonghe(pt.get(i + 1))) { pt.remove(i); } } if(pt.get(0).chonghe(pt.get(pt.size()-1))) { pt.remove(0); } //判断点在两点之间 for (int i = 0; i < pt.size(); i++) { if(Line.threeline(pt.get(i%pt.size()),pt.get((i+1)%pt.size()),pt.get((i+2)%pt.size()))) { pt.remove((i+1)%pt.size()); } } } public static double sswr(double s) { String str=String.valueOf(s); String substring = str.substring(str.indexOf(".") + 1); int str_len; if(substring.length()>3) { str_len=3; }else { str_len=substring.length(); } String formats="%."+str_len+"f"; String out=String.format(formats,s); double res=Double.parseDouble(out); return res; } } class Point { private double x; private double 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 distance(Point a) { double dis; dis = Math.sqrt(Math.pow((a.x - this.x),2) + Math.pow((a.y - this.y),2)); return dis; } public boolean CheckPoint(Point p){ if( Math.abs(this.getX() - p.getX() )< 0.000001 && Math.abs(this.getY() - p.getY() )< 0.000001){ return true; } else return false; } public boolean chonghe(Point a){ if(this.getX() == a.getX() && this.getY() == a.getY()) return true; return false; } } class Line { private Point m,n; private double b;//y=kx+b private double k; private double A; private double B; private double C; public Line() { } public Line(Point m,Point n) { this.m = m; this.n = n; this.slope(); this.equation(m,n);//求出直线方程 } public void setMN(Point m,Point n) { this.m = m; this.n = n; this.slope(); this.equation(m,n);//求出直线方程 } public Point getM() { return m; } public Point getN() { return n; } public double getA() { return A; } public double getC() { return C; } public double getK() { return k; } public double getB() { return B; } //直线的斜率 public void slope() { double se; if(m.getX() == n.getX()) k = POSITIVE_INFINITY; else if(m.getY() == n.getY()) k = 0; else { se = (m.getY()-n.getY())/(m.getX()-n.getX()); k = se; } } public void equation(Point m,Point n) { double b; b = m.getY() - this.k * m.getX(); A = n.getY() - m.getY(); B = m.getX() - n.getX(); C = n.getX() * m.getY() - m.getX() * n.getY(); } //点到直线的距离 double p_to_l(Point a,Line l) { //double dis = Math.abs(l.getA()*a.getX() + l.getB()*a.getY() + l.getC())/Math.sqrt(l.A * l.A + l.B* l.B); //return dis; if(l.k == 0) { return Math.abs(l.getM().getX()-a.getX()); } else if(l.k == 1) { return Math.abs(l.getM().getY()-a.getY()); } else { return Math.abs(l.getK()*a.getX()-a.getY()+ this.b)/(Math.sqrt(1+l.getK()*l.getK())); } } //判断三点一线,用于判断选项四的三角形情况 public static boolean threeline(Point a, Point b, Point c) { Line line1 = new Line(); line1.setMN(a,c); return line1.isallline(b) && line1.pointupline(b); } public boolean fourpoint(Line a) { if(Math.abs(a.k - this.k) < 0.000001) return true; else return false; } //求两直线交点坐标 public Point intersection(Line a) { Point point = new Point(); double det = this.getA() * a.getB() - a.getA() * this.getB(); point.setX(( this.getB() * a.getC() - a.getB() * this.getC() )/det); point.setY(( a.getA() * this.getC() - this.getA() * a.getC() )/det); return point; } //点在线端内,点到线上两端点的距离==两端点距离 public boolean pointupline(Point a) { if(Math.abs(a.distance(this.getM()) + a.distance(this.getN()) - this.distance()) < 0.000001) return true; else return false; } //点在线上不包含端点 public boolean pointupline2(Point a) { if(this.pointupline(a) && !this.getM().chonghe(a) && !this.getN().chonghe(a)) return true; return false; } //点是否在直线上 public boolean isallline(Point a) { if(Math.abs( getA() * a.getX() + getB() * a.getY() + getC() ) < 0.000001) return true; return false; } //线段距离 public double distance() { double dis; dis = Math.sqrt(Math.pow((m.getX() - n.getX()),2) + Math.pow((m.getY() - n.getY()),2)); return dis; } //判断两点是否在直线一侧 public boolean istongce(Point a,Point b) { double x1; double x2; x1 = this.getA() * a.getX() + this.getB() * a.getY() + this.getC(); x2 = this.getA() * b.getX() + this.getB() * b.getY() + this.getC(); if(x1 * x2 > 0) return true; else return false; } //判断两条线重合 public boolean chonghe(Line l) { if(this.isallline(l.getM()) && this.isallline(l.getN())) { return true; } return false; } } class triangle { private Line l1 = new Line(); private Line l2 = new Line(); private Line l3 = new Line(); public triangle(Line l1, Line l2, Line l3) { this.l1 = l1; this.l2 = l2; this.l3 = l3; } public triangle(Point a, Point b, Point c) { this.l1.setMN(a, b); this.l2.setMN(b, c); this.l3.setMN(c, a); } public Line getL1() { return l1; } public void setL1(Line l1) { this.l1 = l1; } public Line getL2() { return l2; } public void setL2(Line l2) { this.l2 = l2; } public Line getL3() { return l3; } public void setL3(Line l3) { this.l3 = l3; } //是否能构成三角形 public boolean istriangle() { if (l1.isallline(l2.getN()) || l2.isallline(l3.getN()) || l3.isallline(l1.getN())) return false; return true; } //等腰三角形 public boolean istwoline() { if (Math.abs(l1.distance() - l2.distance()) < 0.000001 || Math.abs(l2.distance() - l3.distance()) < 0.000001 || Math.abs(l2.distance() - l3.distance()) < 0.000001) { return true; } else return false; } //等边三角形 public boolean threeline() { if (Math.abs(l1.distance() - l2.distance()) < 0.000001 && Math.abs(l1.distance() - l3.distance()) < 0.000001 && Math.abs(l2.distance() - l3.distance()) < 0.000001) { return true; } else return false; } //三角形周长 public double Perimeter() { return l1.distance() + l2.distance() + l3.distance(); } //三角形面积 public double area() { double s = this.Perimeter() * 0.5; return Math.sqrt(s * (s - l1.distance()) * (s - l2.distance()) * (s - l3.distance())); } public double area3(){ return l1.p_to_l(l1.getM(),l1) * l1.distance() *0.5; } public double area2(Point a, Point b, Point c) { double d1, d2, d3; d1 = a.distance(b); d2 = b.distance(c); d3 = a.distance(c); double s = 0.5 * (d1 + d2 + d3); return Math.sqrt(s * (s - d1) * (s - d2) * (s - d3)); } //重心 public Point focus() { Point weight = new Point(); weight.setX((l1.getM().getX() + l1.getN().getX() + l2.getN().getX()) * 1.0 / 3); weight.setY((l1.getM().getY() + l1.getN().getY() + l2.getN().getY()) * 1.0 / 3); return weight; } //求余弦 public double[] getcos() { double[] cos = new double[3]; cos[0] = (l1.distance() * l1.distance() + l2.distance() * l2.distance() - l3.distance() * l3.distance()) / (2 * l1.distance() * l2.distance()); cos[1] = (l1.distance() * l1.distance() + l3.distance() * l3.distance() - l2.distance() * l2.distance()) / (2 * l1.distance() * l3.distance()); cos[2] = (l3.distance() * l3.distance() + l2.distance() * l2.distance() - l1.distance() * l1.distance()) / (2 * l3.distance() * l2.distance()); return cos; } public double getcos(Point a, Point b, Point c) { double l1 = a.distance(b); double l2 = a.distance(c); double l3 = b.distance(c); return (l1 * l1 + l2 * l2 - l3 * l3) / (2 * l1 * l2); } // 点在三角形的边上 public boolean pupline(Point a) { if(l1.pointupline(a) && l1.isallline(a)){ return true; } else if(l2.isallline(a) && l2.pointupline(a)) { return true; } else if(l3.pointupline(a) && l3.isallline(a)) { return true; } else return false; } //点在三角形内 public boolean pupin(Point a) { triangle tl1 = new triangle(l1.getM(), l1.getN(), a); triangle tl2 = new triangle(l2.getM(), l2.getN(), a); triangle tl3 = new triangle(l3.getM(), l3.getN(), a); if(!this.pupline(a) && Math.abs(tl1.area() + tl2.area() + tl3.area() - this.area()) < 0.0001) return true; return false; } public boolean chonghe(Line l) { if(l1.chonghe(l)) return true; if(l2.chonghe(l)) return true; if(l3.chonghe(l)) return true; return false; } public void OneTriangle(Line line){ List<Line> lineList = new ArrayList<>(); lineList.add(l1);lineList.add(l2);lineList.add(l3); List<Point> list = new ArrayList<>(); int cnt = 0; Point u; for(int i=0;i<lineList.size();i++){ u = lineList.get(i).intersection(line); boolean flag = false; if( u != null){ if(lineList.get(i).pointupline(u)){ flag = true; } for (Point p : list){ if( p.CheckPoint(u) ){ flag = false; break; } } if(flag){ list.add(u); //System.out.println(u.getX() + " " + u.getY() ); cnt++; } } } if(cnt < 2){ System.out.println(cnt); } else { double s1,s2,s; System.out.print("2 "); Line lline = new Line(list.get(0), list.get(1)); Point p1 = list.get(0),p2 = list.get(1); Point m; if(l1.isallline(p1) && l2.isallline(p2) || l2.isallline(p2) && l1.isallline(p1)) m = l1.getN(); else if( l1.isallline(p1) && l3.isallline(p2) || l3.isallline( p2) && l1.isallline(p1) ) m = l1.getM(); else m = l2.getN(); triangle triangle1 = new triangle(m,list.get(0),list.get(1)); s1 = triangle1.area(); s1 = Judge.sswr(s1); s = this.area(); s = Judge.sswr(s); s2 = s - s1; s2 = Judge.sswr(s2); System.out.println(Math.min(s1,s2) + " " + Math.max(s1,s2)); } } } class quadrilateral { private Line line01; private Line line02; private Line line03; private Line line04; Point[] point = new Point[4]; public quadrilateral(Point a,Point b,Point c,Point d) { point[0] = a;point[1] = b;point[2] = c; point[3] = d; Line line01 = new Line(a,b); this.line01 = line01; Line line02 = new Line(b,c); this.line02 = line02; Line line03 = new Line(c,d); this.line03 = line03; Line line04 = new Line(d,a); this.line04 = line04; } public boolean isquadrilateral() { if((line01.getK() == line02.getK() || line02.getK() == line03.getK() || line03.getK() == line04.getK() || line04.getK() == line01.getK()) || (line01.pointupline(line01.intersection(line03)) && line03.pointupline(line01.intersection(line03))) || (line02.pointupline(line02.intersection(line04)) && line04.pointupline(line02.intersection(line04)))) { return false; } else { return true; } } public boolean ispingxing() { if(line01.getK() == line03.getK() && line02.getK() == line04.getK()){ return true; } else return false; } public boolean islingxing() { if(this.ispingxing() && this.line01.distance() == this.line02.distance() && this.line01.distance() == this.line03.distance() && this.line01.distance() == this.line04.distance()) { return true; } else return false; } public boolean isjuxing() { if(this.ispingxing() && ( (this.line01.getK() == POSITIVE_INFINITY && this.line02.getK() == 0) || (this.line01.getK() == 0 && this.line02.getK() == POSITIVE_INFINITY) || this.line01.getK() * this.line02.getK() == -1)) { return true; } else return false; } public boolean iszhengfangxing() { if(this.isjuxing() && this.islingxing()) { return true; } else return false; } //判断凸四边形 public boolean istusibainxing() { if(line01.istongce(line03.getM(),line03.getN()) && line02.istongce(line04.getM(),line04.getN()) && line03.istongce(line01.getM(),line01.getN()) && line04.istongce(line02.getM(),line02.getN())) { return true; } else return false; } //四边形周长 public double perimeter() { return line01.distance() + line02.distance() + line03.distance() + line04.distance(); } //四边形面积 public double area() { triangle triangle01 = new triangle(line01.getM(), line01.getN(), line02.getN()); triangle triangle02 = new triangle(line03.getM(), line03.getN(), line04.getN()); triangle triangle03 = new triangle(line02.getM(), line02.getN(), line03.getN()); triangle triangle04 = new triangle(line04.getM(), line04.getN(), line01.getN()); double qarea01,qarea02; qarea01 = triangle01.area() + triangle02.area(); qarea02 = triangle03.area() + triangle04.area(); if(qarea02 < qarea01)//凹四边形面积比较特殊,要找凹点,这里偷懒直接判段小的输出 return qarea02; else return qarea01; } //点在四边形边上 public boolean pupline(Point a) { if(line01.pointupline(a) && line01.isallline(a)) return true; else if(line02.pointupline(a) && line02.isallline(a)) return true; else if(line03.pointupline(a) && line03.isallline(a)) return true; else if(line04.pointupline(a) && line04.isallline(a)) return true; else return false; } //点在四边形内部 public boolean pupin(Point a) { triangle tl01 = new triangle(line01.getM(), line01.getN(), a); triangle tl02 = new triangle(line02.getM(), line02.getN(), a); triangle tl03 = new triangle(line03.getM(), line03.getN(), a); triangle tl04 = new triangle(line04.getM(), line04.getN(), a); if(!this.pupline(a) && Math.abs(tl01.area() + tl02.area() + tl03.area() + tl04.area() - this.area()) < 0.0001) return true; else return false; } public boolean chonghe(Line l) { if(line01.chonghe(l)) return true; if(line02.chonghe(l)) return true; if(line03.chonghe(l)) return true; if(line04.chonghe(l)) return true; return false; } //四边形分割成两个求面积,有两个交点 public void fengeArea(Point a,Point b,Point c) { triangle tr1 = new triangle(a,b,c); double area1 = tr1.area(); double area = this.area(); double area2 = area - area1; area1 = Judge.sswr(area1); area2 = Judge.sswr(area2); System.out.println("2 " + Math.min(area1,area2) + " " + Math.max(area1,area2)); } public void Onequarilateral(Line l) { Point[] points = new Point[4]; ArrayList<Line> lines = new ArrayList<>(); lines.add(line01);lines.add(line02);lines.add(line03);lines.add(line04); int[] p_in = new int[4]; //判断交点在线上还是端点 for (int i = 0; i < 4; i++) { p_in[i] = 0; //求直线与四边形的交点 points[i] = lines.get(i).intersection(l); if(points[i]!=null) { //判断交点是否在边上,不包括端点 if(lines.get(i).pointupline2(points[i])) p_in[i] = 1; } } //有顶角在线上 for (int i = 0; i < 4; i++) { if(l.isallline(point[i])) { if(l.isallline((point[(i+2)%4]))) { fengeArea(point[i], point[(i + 2) % 4], point[(i + 1) % 4]); return; } else if(p_in[(i+1)%4] == 1) { fengeArea(point[i], point[(i + 1) % 4], points[(i + 1) % 4]); return; } else if(p_in[(i+2)%4] == 1) { fengeArea(point[i], point[(i + 3) % 4], points[(i + 2) % 4]); return; } else { System.out.println("1"); return; } } } //两个临边 for (int i = 0; i < 4; i++) { if(p_in[i] == 1 && p_in[(i+1)%4] == 1) { fengeArea(point[(i + 1) % 4], points[i], points[(i + 1) % 4]); return; } } //两个对边 for (int i = 0; i < 2; i++) { if(p_in[i] == 1 && p_in[i+2] == 1) { triangle tr1 = new triangle(point[i], points[i], points[(i + 2) % 4]); triangle tr2 = new triangle(point[(i+3)%4], point[i], points[(i + 2) % 4]); double area1 = tr1.area() + tr2.area(); double area = this.area(); double area2 = area - area1; area1 = Judge.sswr(area1); area2 = Judge.sswr(area2); System.out.println("2 " + Math.min(area1,area2) + " " + Math.max(area1,area2)); return; } } System.out.println("0"); return; } }
先利用check方法(正则表达式)检查一下输入进来的字符串,然后根据第一位是什么数字进入执行对应的方法。
用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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
详细信息及样例请查看附件,本题包含附件中的选项1-3的功能:
类图:
代码软件分析:
代码主要类:
public static boolean geshi(String s){ String s2= s.substring(0,2); if(!s2.matches("[1-6]\\:")) { System.out.println("Wrong Format"); return false; } String s3 = s.substring(2); if(!s3.matches("([+|-]?(0|[1-9][0-9]*)(\\.\\d+)?,[+|-]?(0|[1-9][0-9]*)(\\.\\d+)?\\ ?)+")) { System.out.println("Wrong Format"); return false; } return true; } public static boolean dianshu(String s){ String[] a = s.split(":"); String[] b = a[1].split(" "); int n = b.length; if (s.charAt(0) == '1' && n != 5) { System.out.println("wrong number of points"); return false; } else if (s.charAt(0) == '2' && n != 5) { System.out.println("wrong number of points"); return false; } else if (s.charAt(0) == '3' && n != 7) { System.out.println("wrong number of points"); return false; } else if (s.charAt(0) == '4' && n != 10) { System.out.println("wrong number of points"); return false; } else if (s.charAt(0) == '6' && n != 6) { System.out.println("wrong number of points"); return false; } return true; } static class Wubianxing { Point a,b,c,d,e; Line ab,bc,cd,de,ea,ac,ad,bd,be,ce; Wubianxing(Point a,Point b,Point c,Point d,Point e){ this.a=a;this.b=b;this.c=c;this.d=d;this.e=e; this.ab=new Line(a,b); this.bc=new Line(b,c); this.cd=new Line(c,d); this.de=new Line(d,e); this.ea=new Line(e,a); this.ac=new Line(a,c); this.ad=new Line(a,d); this.bd=new Line(b,d); this.be=new Line(b,e); this.ce=new Line(c,e); } public boolean iswubianxing(){ if(ab.pingxing(bc)||bc.pingxing(cd)||cd.pingxing(de)||de.pingxing(ea)){ return false; } else if(Line.intersect(a.x,a.y,b.x,b.y,c.x,c.y,d.x,d.y)||Line.intersect(a.x,a.y,b.x,b.y,d.x,d.y,e.x,e.y)|| Line.intersect(b.x,b.y,c.x,c.y,d.x,d.y,e.x,e.y)||Line.intersect(b.x,b.y,c.x,c.y,e.x,e.y,a.x,a.y)|| Line.intersect(c.x,c.y,d.x,d.y,e.x,e.y,a.x,a.y)) return false; return true; } public boolean istuwubianxing(){ if((((b.x-a.x)*(c.y-b.y))-((c.x-b.x)*(b.y-a.y))>0&&((c.x-b.x)*(d.y-c.y))-((d.x-c.x)*(c.y-b.y))>0&& ((d.x-c.x)*(e.y-d.y))-((e.x-d.x)*(d.y-c.y))>0&&((e.x-d.x)*(a.y-e.y))-((a.x-e.x)*(e.y-d.y))>0)|| (((b.x-a.x)*(c.y-b.y))-((c.x-b.x)*(b.y-a.y))<0&&((c.x-b.x)*(d.y-c.y))-((d.x-c.x)*(c.y-b.y))<0&& ((d.x-c.x)*(e.y-d.y))-((e.x-d.x)*(d.y-c.y))<0&&((e.x-d.x)*(a.y-e.y))-((a.x-e.x)*(e.y-d.y))<0)) return true; else return false; } public double zhouchang(){ double c=this.ab.length()+this.bc.length()+this.cd.length()+this.de.length()+this.ea.length(); double C=outformat(c); return C; } public double area(){ Sanjiao san1=new Sanjiao(this.a,this.b,this.c); Sanjiao san2=new Sanjiao(this.a,this.c,this.d); Sanjiao san3=new Sanjiao(this.a,this.d,this.e); double mj= san1.mianji()+ san2.mianji()+ san3.mianji(); double mianji=outformat(mj); return mianji; } public Double outformat(double num) { if(num*1e+3%10!=0) { String num1=String.format("%.3f",num); return Double.valueOf(num1); } return num; } public boolean bianchonghe (Line l){ if(this.ab.xianchonghe(l)){ return true; } else if(this.bc.xianchonghe(l)){ return true; } else if(this.cd.xianchonghe(l)){ return true; } else if(this.de.xianchonghe(l)){ return true; } else if(this.ea.xianchonghe(l)){ return true; } return false; } public void fengewubainxing(Line l) { double area1=0,area2=0; if(this.ac.xianchonghe(l)){ Sanjiao ss1=new Sanjiao(this.a,this.b,this.c); area1=ss1.mianji(); area2=this.area()-area1; out(area1,area2); } else if(this.ad.xianchonghe(l)){ Sanjiao ss1=new Sanjiao(this.a,this.d,this.e); area1=ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.bd.xianchonghe(l)){ Sanjiao ss1=new Sanjiao(this.b,this.d,this.c); area1=ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.be.xianchonghe(l)){ Sanjiao ss1=new Sanjiao(this.a,this.b,this.e); area1=ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.ce.xianchonghe(l)){ Sanjiao ss1=new Sanjiao(this.c,this.d,this.e); area1=ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.ab.jiaodian(l)!=null&&this.bc.jiaodian(l)!=null&&this.ab.jiaodian(l)!=this.bc.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.ab.jiaodian(l),this.b,this.bc.jiaodian(l)); area1= ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.ab.jiaodian(l)!=null&&this.cd.jiaodian(l)!=null){ Sibian ss1=new Sibian(this.ab.jiaodian(l),this.b,this.c,this.cd.jiaodian(l)); ss1.otupanduan(); area1= ss1.area(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.ab.jiaodian(l)!=null&&this.de.jiaodian(l)!=null){ Sibian ss1=new Sibian(this.a,this.ab.jiaodian(l),this.de.jiaodian(l),this.e); ss1.otupanduan(); area1= ss1.area(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.ab.jiaodian(l)!=null&&this.ea.jiaodian(l)!=null&&this.ab.jiaodian(l)!=this.ea.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.ab.jiaodian(l),this.a,this.ea.jiaodian(l)); area1= ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.bc.jiaodian(l)!=null&&this.cd.jiaodian(l)!=null&&this.bc.jiaodian(l)!=this.cd.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.bc.jiaodian(l),this.c,this.cd.jiaodian(l)); area1= ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.bc.jiaodian(l)!=null&&this.de.jiaodian(l)!=null){ Sibian ss1=new Sibian(this.bc.jiaodian(l),this.c,this.d,this.de.jiaodian(l)); ss1.otupanduan(); area1= ss1.area(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.bc.jiaodian(l)!=null&&this.ea.jiaodian(l)!=null){ Sibian ss1=new Sibian(this.bc.jiaodian(l),this.ea.jiaodian(l),this.a,this.b); ss1.otupanduan(); area1= ss1.area(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.cd.jiaodian(l)!=null&&this.de.jiaodian(l)!=null&&this.cd.jiaodian(l)!=this.de.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.cd.jiaodian(l),this.d,this.de.jiaodian(l)); area1= ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.cd.jiaodian(l)!=null&&this.ea.jiaodian(l)!=null){ Sibian ss1=new Sibian(this.cd.jiaodian(l),this.ea.jiaodian(l),this.e,this.d); ss1.otupanduan(); area1= ss1.area(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.de.jiaodian(l)!=null&&this.ea.jiaodian(l)!=null&&this.ea.jiaodian(l)!=this.de.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.ea.jiaodian(l),this.e,this.de.jiaodian(l)); area1= ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else { System.out.println(0); System.exit(0); } } public void out(double m1,double m2){ if(m1>=m2){ System.out.println(2+" "+m2+" "+m1); System.exit(0); } else{ System.out.println(2+" "+m1+" "+m2); System.exit(0); } } public boolean inwubianxing(Point p){ Sanjiao ss1=new Sanjiao(this.a,this.b,p);Sanjiao ss2=new Sanjiao(this.b,this.c,p); Sanjiao ss3=new Sanjiao(this.c,this.d,p);Sanjiao ss4=new Sanjiao(this.d,this.e,p); Sanjiao ss5=new Sanjiao(this.e,this.a,p); if(Math.abs(this.area()-(ss1.mianji()+ss2.mianji()+ss3.mianji()+ss4.mianji()+ss5.mianji()))<0.0001) return true; else return false; } } static class Line { Point x,y; Line (Point a, Point b){ this.x=a; this.y=b; } double length(){ return this.x.juli(this.y); } double distance(Point p){//!!! if(this.x.x==this.y.x){ return (p.x-this.x.x); } else{ double e=(this.x.y-this.y.y)/(this.x.x-this.y.x); double b=this.x.y-(e*this.x.x); return (e*p.x-p.y+b)/Math.sqrt(e*e+1); } } public static boolean intersect(double l1x1,double l1y1,double l1x2,double l1y2,double l2x1,double l2y1,double l2x2,double l2y2) { // 快速排斥实验 首先判断两条线段在 x 以及 y 坐标的投影是否有重合。 有一个为真,则代表两线段必不可交。 if (Math.max(l1x1,l1x2) < Math.min(l2x1 ,l2x2) || Math.max(l1y1,l1y2) < Math.min(l2y1,l2y2) || Math.max(l2x1,l2x2) < Math.min(l1x1,l1x2) || Math.max(l2y1,l2y2) < Math.min(l1y1,l1y2)) { return false; } // 跨立实验 如果相交则矢量叉积异号或为零,大于零则不相交 else if ((((l1x1 - l2x1) * (l2y2 - l2y1) - (l1y1 - l2y1) * (l2x2 - l2x1)) * ((l1x2 - l2x1) * (l2y2 - l2y1) - (l1y2 - l2y1) * (l2x2 - l2x1))) > 0 || (((l2x1 - l1x1) * (l1y2 - l1y1) - (l2y1 - l1y1) * (l1x2 - l1x1)) * ((l2x2 - l1x1) * (l1y2 - l1y1) - (l2y2 - l1y1) * (l1x2 - l1x1))) > 0) { return false; } return true; } public double duijiaoxian() { double duijiaoxian=Math.sqrt((this.x.x-this.y.x)*(this.x.x-this.y.x)+(this.x.y-this.y.y)*(this.x.y-this.y.y)); return duijiaoxian; } public boolean xianchonghe (Line l){ return this.pingxing(l)&&l.distance(this.x)==0; } boolean inline(Point p){ if(this.x.x==this.y.x&&this.y.x==p.x) return true; double e=(this.x.y-this.y.y)/(this.x.x-this.y.x); double b=this.x.y-(e*this.x.x); if((((e*p.x-p.y+b)==0&&(p.x>=min(x.x,y.x)&&p.x<=max(x.x,y.x)))&&((e*p.x-p.y+b)==0&&(p.y>=min(x.y,y.y)&&p.y<=max(x.y,y.y))))) return true; else return false; } Point jiaodian(Line l){ Point v=sub(l.y,l.x); Point w=sub(this.y,this.x); Point p=l.x; Point q=this.x; Point u=sub(p,q); double t=cross(w,u)/cross(v,w); Point ans =new Point( p.x+v.x*t,p.y+v.y*t); double y0=ans.y; double x0=ans.x; if(((x0)>=min(x.x,y.x)&&(x0)<=max(x.x,y.x))&&((y0)>=min(x.y,y.y)&&(y0)<=max(x.y,y.y))) return ans; return null; } public static double cross (Point a, Point b){ return a.x*b.y-a.y*b.x; } public static Point sub(Point a, Point b){ return new Point(a.x-b.x,a.y-b.y); } boolean pingxing (Line a){ if((a.x.x==a.y.x )&&(this.x.x==this.y.x)) return true; if((a.x.x==a.y.x)&&(this.x.x!=this.y.x)) return false; if((a.x.x!=a.y.x)&&(this.x.x==this.y.x)) return false; double e=a.x.xilv(a.y); double e1=this.x.xilv(this.y); if(e==e1) return true; else return false; } } static class Point { double x,y; Point(double a,double b){ this.x=a; this.y=b; } public double getx(){ return x; } public double gety(){ return y; } public double juli(Point p){ return Math.sqrt((this.x-p.x )*(this.x-p.x )+(this.y-p.y )*(this.y-p.y)); } public double xilv(Point p){ if(this.x==p.x){ System.out.println("Slope does not exist"); System.exit(0); } return (this.y-p.y)/(this.x-p.x); } } static class Sanjiao { Main.Point sx,sy,sz; Main.Line sa,sb,sc; Sanjiao (Main.Point a, Main.Point b, Main.Point c){ this.sx=a; this.sy=b; this.sz=c; this.sa=new Main.Line(b,c); this.sb=new Main.Line(a,c); this.sc=new Main.Line(a,b); } public boolean gouchengsanjiao(){ if(((this.sa.length()+this.sb.length())<=this.sc.length())||((this.sa.length()+this.sc.length())<=this.sb.length())||((this.sb.length()+this.sc.length())<=this.sa.length())){ return false; } else return true; } public double zhouchang(){ return (this.sa.length()+this.sb.length()+this.sc.length()); } public double mianji(){ double area=0; double s=(this.sa.length()+this.sb.length()+this.sc.length())/2; return area=Math.sqrt(s*(s-this.sa.length())*(s-this.sb.length())*(s-this.sc.length())); } public int type(){ double[] num = new double[3]; num[0] = this.sa.length();num[1] = this.sb.length();num[2] = this.sc.length(); Arrays.sort(num); double tmp = Math.pow(num[0],2) + Math.pow(num[1],2) - Math.pow(num[2],2); if(Math.abs(tmp) < 0.0000001) return 1; if(tmp < 0) return 2; return 0; } public boolean insanjiao(Main.Point p){ Sanjiao san1=new Sanjiao(p,sx,sy); Sanjiao san2=new Sanjiao(p,sy,sz); Sanjiao san3=new Sanjiao(p,sz,sx); double m1=san1.mianji(); double m2=san2.mianji(); double m3=san3.mianji(); if(Math.abs(this.mianji()-(m1+m2+m3))<0.0001) return true; else return false; } public void fengesanjiaoxing(Line l){ double area1=0,area2=0; if(this.sc.jiaodian(l)!=null&&this.sa.jiaodian(l)!=null&&this.sc.jiaodian(l)!=this.sa.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.sc.jiaodian(l),this.sy,this.sa.jiaodian(l)); area1=ss1.mianji(); area2=this.mianji()-area1; double mj1=outformat( area1); double mj2=outformat( area2); out(mj1,mj2); } else if(this.sc.jiaodian(l)!=null&&this.sb.jiaodian(l)!=null&&this.sc.jiaodian(l)!=this.sb.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.sc.jiaodian(l),this.sb.jiaodian(l),this.sx); area1=ss1.mianji(); area2=this.mianji()-area1; double mj1=outformat( area1); double mj2=outformat( area2); out(mj1,mj2); } else if(this.sa.jiaodian(l)!=null&&this.sb.jiaodian(l)!=null&&this.sa.jiaodian(l)!=this.sb.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.sa.jiaodian(l),this.sz,this.sb.jiaodian(l)); area1=ss1.mianji(); area2=this.mianji()-area1; double mj1=outformat( area1); double mj2=outformat( area2); out(mj1,mj2); } else { System.out.println(0); System.exit(0); } } public Double outformat(double num) { if(num*1e+3%10!=0) { String num1=String.format("%.3f",num); return Double.valueOf(num1); } return num; } public void out(double m1,double m2){ if(m1>=m2){ System.out.println(2+" "+m2+" "+m1); System.exit(0); } else{ System.out.println(2+" "+m1+" "+m2); System.exit(0); } } public boolean bianchonghe(Line l){ if(this.sa.xianchonghe(l)) return false; else if(this.sb.xianchonghe(l)) return false; else if(this.sc.xianchonghe(l)) return false; else return true; } } static class Sibian { Main.Point a,b,c,d; Main.Line ab,bc,cd,da,ac,bd; private boolean judge1=false;//0,2 private boolean judge2=false;//1,3 Sibian(Main.Point a, Main.Point b, Main.Point c, Main.Point d){ this.a=a;this.b=b;this.c=c;this.d=d; this.ab=new Main.Line(a,b); this.bc=new Main.Line(b,c); this.cd=new Main.Line(c,d); this.da=new Main.Line(d,a); this.ac=new Main.Line(a,c); this.bd=new Main.Line(b,d); } public void sibianxing(){ if(Math.abs((a.y-c.y)*(a.x-b.x)-(a.y-b.y)*(a.x-c.x))<1e-6|| Math.abs((a.y-d.y)*(a.x-b.x)-(a.y-b.y)*(a.x-d.x))<1e-6|| Math.abs((a.y-d.y)*(a.x-c.x)-(a.y-c.y)*(a.x-d.x))<1e-6|| Math.abs((b.y-d.y)*(b.x-c.x)-(b.y-c.y)*(b.x-d.x))<1e-6)System.out.print("false "); else { if(!Main.Line.intersect(a.x,a.y,d.x,d.y,b.x,b.y,c.x,c.y)) { System.out.print("true "); } else System.out.print("false "); } } public void pingxingsibianxing(){ if(this.ab.length()==this.cd.length()&&this.bc.length()==this.da.length())System.out.print("true"); else System.out.print("false"); } public boolean nengfougoucheng(){ if(Math.abs((a.y-c.y)*(a.x-b.x)-(a.y-b.y)*(a.x-c.x))<1e-6|| Math.abs((a.y-d.y)*(a.x-b.x)-(a.y-b.y)*(a.x-d.x))<1e-6|| Math.abs((a.y-d.y)*(a.x-c.x)-(a.y-c.y)*(a.x-d.x))<1e-6|| Math.abs((b.y-d.y)*(b.x-c.x)-(b.y-c.y)*(b.x-d.x))<1e-6) { return false; } else return !Main.Line.intersect(a.x, a.y, d.x, d.y, b.x, b.y, c.x, c.y) && !Main.Line.intersect(a.x, a.y, b.x, b.y, d.x, d.y, c.x, c.y); } public boolean lingxing(){ return (this.ab.length()==this.cd.length()&&this.bc.length()==this.da.length()); } public boolean changfangxing(){ Main.Line l1=new Main.Line(a,c); double ac=l1.duijiaoxian(); Main.Line l2=new Main.Line(b,d); double bd=l2.duijiaoxian(); return (ac==bd&&this.ab.length()==this.cd.length()&&this.bc.length()==this.da.length()); } public boolean zhengfangxing(){ return (lingxing()&& changfangxing()); } public boolean otupanduan() { Main.Line l1=new Main.Line(a,c); double distance1=l1.distance(b); double distance2=l1.distance(d); Main.Line l2=new Main.Line(b,d); double distance3=l2.distance(a); double distance4= l2.distance(c); if(distance1*distance2<0)judge1=true; if(distance3*distance4<0)judge2=true; if(judge1==true&&judge2==true) { return true; } return false; } public double zhouchang() { double ab=this.ab.length(); double bc=this.bc.length(); double cd=this.cd.length(); double da=this.da.length(); double c=ab+bc+cd+da; double C=outformat(c); return C; } public double area() { double area=0; double area1=0; double area2=0; double are=0; //凸四边形 if(judge1==true&&judge2==true) { area1=Math.abs((b.x*c.y+c.x*d.y+d.x*b.y-b.x*d.y-c.x*b.y-d.x*c.y)/2); area2=Math.abs((b.x*a.y+a.x*d.y+d.x*b.y-b.x*d.y-a.x*b.y-d.x*a.y)/2); area=area1+area2; are= outformat(area); } else if(judge1==false) { area1=Math.abs((b.x*d.y+d.x*a.y+a.x*b.y-b.x*a.y-d.x*b.y-a.x*d.y)/2); area2=Math.abs((d.x*c.y+c.x*b.y+b.x*d.y-d.x*b.y-c.x*d.y-b.x*c.y)/2); area=area1+area2; are= outformat(area); } else if(judge2==false) { area1=Math.abs((b.x*c.y+c.x*a.y+a.x*b.y-b.x*a.y-c.x*b.y-a.x*c.y)/2); area2=Math.abs((d.x*c.y+c.x*a.y+a.x*d.y-d.x*a.y-c.x*d.y-a.x*c.y)/2); area=area1+area2; are=outformat(area); } return are; } public Double outformat(double num) { if(num*1e+3%10!=0) { String num1=String.format("%.3f",num); return Double.valueOf(num1); } return num; } public boolean bianchonghe (Main.Line l){ if(this.ab.xianchonghe(l)){ return true; } else if(this.bc.xianchonghe(l)){ return true; } else if(this.cd.xianchonghe(l)){ return true; } else if(this.da.xianchonghe(l)){ return true; } return false; } public boolean insibian(Main.Point p){ double m=0; if(otupanduan()){ m=area(); } Main.Sanjiao ss1=new Main.Sanjiao(p,a,b); Main.Sanjiao ss2=new Main.Sanjiao(p,b,c); Main.Sanjiao ss3=new Main.Sanjiao(p,c,d); Main.Sanjiao ss4=new Main.Sanjiao(p,d,a); double m1=ss1.mianji(); double m2=ss2.mianji(); double m3=ss3.mianji(); double m4=ss4.mianji(); if(Math.abs(m-(m1+m2+m3+m4))<0.0001)/*注意一定要三位小数或更多,不然通不过测试点*/ return true; else return false; } public void fengesibianxing(Line l){ double area1=0,area2=0; if(this.ac.xianchonghe(l)){ Sanjiao ss1=new Sanjiao(this.a,this.b,this.c); area1=ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.bd.xianchonghe(l)){ Sanjiao ss1=new Sanjiao(this.a,this.b,this.d); area1=ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.ab.jiaodian(l)!=null&&this.bc.jiaodian(l)!=null&&this.ab.jiaodian(l)!=this.bc.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.ab.jiaodian(l),this.b,this.bc.jiaodian(l)); area1=ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.ab.jiaodian(l)!=null&&this.cd.jiaodian(l)!=null){ Sibian ss1=new Sibian(this.a,this.ab.jiaodian(l),this.cd.jiaodian(l),this.d); area1=ss1.area(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.ab.jiaodian(l)!=null&&this.da.jiaodian(l)!=null&&this.ab.jiaodian(l)!=this.da.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.a,this.ab.jiaodian(l),this.da.jiaodian(l)); area1=ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.bc.jiaodian(l)!=null&&this.cd.jiaodian(l)!=null&&this.bc.jiaodian(l)!=this.cd.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.bc.jiaodian(l),this.c,this.cd.jiaodian(l)); area1=ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.bc.jiaodian(l)!=null&&this.da.jiaodian(l)!=null){ Sibian ss1=new Sibian(this.a,this.b,this.bc.jiaodian(l),this.da.jiaodian(l)); area1=ss1.area(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else if(this.cd.jiaodian(l)!=null&&this.da.jiaodian(l)!=null&&this.da.jiaodian(l)!=this.cd.jiaodian(l)){ Sanjiao ss1=new Sanjiao(this.da.jiaodian(l),this.d,this.cd.jiaodian(l)); area1=ss1.mianji(); area2=this.area()-area1; double mj1= outformat(area1); double mj2= outformat(area2); out(mj1,mj2); } else { System.out.println(0); System.exit(0); } } public void out(double m1,double m2){ if(m1>=m2){ System.out.println(2+" "+m2+" "+m1); System.exit(0); } else{ System.out.println(2+" "+m1+" "+m2); System.exit(0); } } } }
思路是是先判断多边形多个点分别在线的哪一侧,让在同一侧的点与线的交点组成多边形,任何运用多边形类里面的方法,求出相应结果。
用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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
更多样例请查看附件:
点线形系列5-五边形题目详情.pdf
class Point{ public double x, y; public Point(){ this.x = 0; this.y = 0; } public Point(double a,double b){ this.x = a; this.y = b; } public void print(){ String x = String.format("%.6f",this.x); String y = String.format("%.6f",this.y); x = x.replaceAll("0+?$", ""); y = y.replaceAll("0+?$", ""); System.out.printf("(%s , %s)\n",this.x,this.y); } //两点坐标相同 public boolean isSameTo(Point a){ return (this.x == a.x)&&(this.y == a.y); } //两点距离 public double disToPoint(Point another){ return Math.sqrt(Math.pow(this.x-another.x,2) + Math.pow(this.y-another.y,2)); } //点到直线的垂直距离 public double disToLine(Line l){ return Math.abs(l.a*this.x+l.b*this.y+l.c) / Math.sqrt(Math.pow(l.a,2)+Math.pow(l.b,2)); } //判断是否在直线之上 public boolean inLine(Line l){ return Math.abs(l.a*this.x + l.b*this.y + l.c) < 0.000001; } //判断是否在线段之内(包括端点) public boolean inLineSegment_close(Line l){ if(!this.inLine(l)) return false; double res = this.disToPoint(l.sta) + this.disToPoint(l.ed) - l.length(); return Math.abs(res) < 0.000001; } //判断是否在线段之内(不包括端点) public boolean inLineSegment(Line l){ return this.inLineSegment_close(l) && (!this.isSameTo(l.sta)) && (!this.isSameTo(l.ed)); } public Point deepCopy(){ Point res = new Point(); res.x = this.x; res.y = this.y; return res; } public Point add(Point another){ Point res = this.deepCopy(); res.x += another.x; res.y += another.y; return res; } public Point sub(Point another){ Point res = this.deepCopy(); res.x -= another.x; res.y -= another.y; return res; } //求点集重心 public static Point focusPoint(Point[] points ){ Point res = new Point(0,0); for(Point item:points){ res = res.add(item); } res.x /= points.length; res.y /= points.length; return res; } } class Graphical { public int len=0,status=1; //多边形边数,状态 public Point[] points; public Line[] lines; public double sideLength = 0,area = 0; //边长,面积 public boolean isConvexGraphical = true; public String message = "init"; //信息 public Graphical(Point[] points){ this.points = new Point[points.length]; points = this.removeMulti(points); //去除重复点 if(points.length <=2 ){ this.status = -1; this.message = "Not enough points"; return; } //相邻边夹角0则去除中间点,夹角180则status:-1 for(int i=0;i<points.length;i++){ int first = i , second = (i+1)%points.length, third = (i+2)%points.length; try{ Line l1 = new Line(points[first],points[second]); Line l2 = new Line(points[second],points[third]); if( Math.abs(l1.vectorAngle(l2) - Math.PI) < 0.000001 ){ //夹角180 this.status = -1; this.message = "lines reverse coincidence"; return; } else if(Math.abs(l1.vectorAngle(l2)) > 0.000001){ //夹角不为0 this.points[this.len++] = points[second].deepCopy(); } }catch (Exception e){} } this.points = Arrays.copyOf(this.points,this.len); this.lines = new Line[this.len]; //初始化边 for(int i=0;i<this.len;i++){ try { int first = i, second = (i+1)%this.len; this.lines[i] = new Line(this.points[first], this.points[second]); }catch (Exception e){} } //判断任意不相邻边(线段交点)是否有交点 checkEdge(); Graphical.area(this); Graphical.sideLength(this); Graphical.checkConvex(this); } public void print(){ if(this.status == -1){ System.out.println(this.message); return; } System.out.println("点数为:"+this.len); for(int i=0;i<this.len;i++){ this.points[i].print(); } for(int i=0;i<this.len;i++){ this.lines[i].print(); } System.out.println("周长为:"+this.sideLength); System.out.println("面积为:"+this.area); System.out.println("凹凸性:"+this.isConvexGraphical); } //判断图形是否包含某个点返回值-1,0,1 (内部,边缘,外部) //由于只考虑凸多边形,用面积法就行 public int isContainPoint(Point p){ for(int i=0;i<this.len;i++){ //位于边之上 if(p.inLineSegment_close(this.lines[i])) return 0; } double s = 0; for(int i=0;i<this.len;i++){ s += Triangle.area(p,this.points[i], this.points[(i+1)%this.len]); } return Math.abs(s-this.area) < 0.000001 ? -1:1; } //判断两个图形类之间的关系() public String relationshipWith(Graphical g){ String[] name = new String[]{"triangle", "quadrilateral", "pentagon"}; //分离 if(this.isSeparatedFrom(g)){ return "no overlapping area between the previous "+name[this.len-3]+ " and the following "+name[g.len-3]; } //完全重合 if(this.isSameTo(g)) return "the previous "+name[this.len-3]+ " coincides with the following "+name[g.len-3]; //包含 if(this.isContainGra(g)){ return "the previous "+name[this.len-3]+ " contains the following "+name[g.len-3]; } //被包含 if(g.isContainGra(this)){ return "the previous "+name[this.len-3]+ " is inside the following "+name[g.len-3]; } //连接 if(this.overlappingArea(g) == 0){ return "the previous "+name[this.len-3]+ " is connected to the following "+name[g.len-3]; } //交错 return "the previous "+name[this.len-3]+ " is interlaced with the following "+name[g.len-3]; } //判断和另一个图形完全分离(重叠面积为0,并且任意点都在this之外) public boolean isSeparatedFrom(Graphical g){ boolean ok = true; int[] check2 = new int[g.len]; for(int i=0;i<g.len;i++){ check2[i] = this.isContainPoint(g.points[i]); } for(int item:check2){ if(item != 1) ok = false; } if(this.overlappingArea(g) !=0) ok = false; return ok; } //判断完全包含另一个图形(任意点都在this之内) public boolean isContainGra(Graphical g){ boolean ok = true; int[] check2 = new int[g.len]; for(int i=0;i<g.len;i++){ check2[i] = this.isContainPoint(g.points[i]); } for(int item:check2){ if(item == 1) ok = false; } return ok; } //判断两个图形是否一模一样(点完全重合) public boolean isSameTo(Graphical g){ if(this.len != g.len) return false; for(int i=0;i<this.len;i++){ boolean ok = false; for(int j=0;j<g.len;j++){ if(this.points[i].isSameTo(g.points[j])) ok = true; } if(!ok) return false; } return true; } //计算两个图形的重叠面积(交点加内部顶点构成重叠多边形) public double overlappingArea(Graphical g){ Point[] intersection = new Point[100]; int intersection_len = 0; for(Line item1:this.lines){ //求出两多边形的交点 for(Line item2: g.lines){ Point tmp = item1.lsi(item2); if(tmp != null){ intersection[intersection_len++] = tmp.deepCopy(); } } } for(Point item:g.points){ //顶点包含在内部 if(this.isContainPoint(item) == -1) intersection[intersection_len++] = item.deepCopy(); } for(Point item:this.points){ //顶点包含在内部 if(g.isContainPoint(item) == -1) intersection[intersection_len++] = item.deepCopy(); } //if(intersection_len == 0) return 0; //交点为0,分离 //-2分 /*排序交点数组*/ intersection = Arrays.copyOf(intersection,intersection_len); intersection = this.removeMulti(intersection); Point focus = Point.focusPoint(intersection); Point sta = intersection[0].deepCopy(); Arrays.sort(intersection,1,intersection.length, new Comparator<Point>() { @Override public int compare(Point o1, Point o2) { try{ Line origin =new Line(focus,sta); Line l1 = new Line(focus,o1); Line l2 = new Line(focus,o2); double angle1 = origin.vectorAngle(l1); double angle2 = origin.vectorAngle(l2); if(origin.vectorCrossMul(l1) < 0) angle1 = 2*Math.PI - angle1; if(origin.vectorCrossMul(l2) < 0) angle2 = 2*Math.PI - angle2; if(angle1-angle2 > 0.000001) return 1; if(Math.abs(angle1-angle2) < 0.000001) return 0; return -1; }catch (Exception reason){} return 0; } }); Graphical graphical = new Graphical(intersection); return graphical.area; } //去除所有重复点 private Point[] removeMulti(Point[] points){ Point[] tmp_points = new Point[points.length]; int tmp_len = 0; for(int i=0;i<points.length;i++){ boolean ok = true; for(int j=0;j<tmp_len;j++){ if(points[i].isSameTo(tmp_points[j])){ this.message = "points coincide"; ok = false; break; } } if(ok) tmp_points[tmp_len++] = points[i].deepCopy(); } return Arrays.copyOf(tmp_points,tmp_len); } //判断不相邻边是否有交点 private void checkEdge(){ for(int i=0;i<this.len;i++){ for(int j=i+2;j<this.len;j++){ if(i==0&&j==this.len-1) continue; Point p = this.lines[i].getIntersection(this.lines[j]); if(p==null) continue; if(p.inLineSegment_close(this.lines[i]) && p.inLineSegment_close(this.lines[j])){ this.status = -1; this.message = "Non adjacent edges have intersections"; return; } } } } //多边形面积 private static void area(Graphical e){ double res = 0; Point origin = new Point(0,0); for(int i=0;i<e.len;i++){ try{ Line l1 = new Line(origin,e.points[i]); Line l2 = new Line(origin,e.points[(i+1)%e.len]); res += 0.5 * l1.vectorCrossMul(l2); }catch (Exception reason){} } e.area = Math.abs(res); } //多边形周长 private static void sideLength(Graphical e){ double res = 0; for(int i=0;i<e.len;i++){ res += e.points[i].disToPoint(e.points[(i+1)%e.len]); } e.sideLength = res; } //多边形凹凸性 private static void checkConvex(Graphical e){ if(e.len == 3) return; int v = 0; for(int i=0;i<e.len;i++){ int first = i, second = (i+1)%e.len, thrid = (i+2)%e.len; try{ Line l1 = new Line(e.points[first], e.points[second]); Line l2 = new Line(e.points[first], e.points[thrid]); if(v==0){ if(l1.vectorCrossMul(l2) > 0) v = 1; else v = -1; } if(v == 1 && l1.vectorCrossMul(l2) < 0) e.isConvexGraphical = false; if(v == -1 && l1.vectorCrossMul(l2) > 0) e.isConvexGraphical = false; }catch (Exception reason){} } } //是否一样 }
-
设计一个类表示平面直角坐标系上的点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) { Scanner in = new Scanner(System.in); double x1 = in.nextDouble(); double y1 = in.nextDouble(); double x2 = in.nextDouble(); double y2 = in.nextDouble(); Point a = new Point(x1,y1); Point b = new Point(x2,y2); a.judge(x1,y1); b.judge(x2,y2); String color = in.next(); Line l = new Line(a,b,color); l.display(); } } class Point { private double x; private double y; 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 void display() { System.out.printf("(%.2f,%.2f)", x, y); } public void judge(double x,double y) { if((x<=0||x>200)||(y<=0||y>200)) { System.out.println("Wrong Format"); System.exit(0); } } } class Line{ private Point point1; private Point point2; private String color; private double distance; Line() { } public Line(Point p1, Point p2,String color) { Point p3 = new Point(p1.getX(), p1.getY()); Point p4 = new Point(p2.getX(), p2.getY()); this.point1 = p3; this.point2 = p4; this.color = color; } public void setcolor() { this.color = color; } public String getcolor() { return color; } public double getdistance() { distance = Math.sqrt(Math.abs((point1.getX() - point2.getX())* (point1.getX() - point2.getX())+(point1.getY() - point2.getY())* (point1.getY() - point2.getY()))); this.distance = distance; return distance; } public void display() { double s; s = getdistance(); System.out.println("The line's color is:"+ color); System.out.println("The line's begin point's Coordinate is:"); point1.display(); System.out.println("\nThe line's end point's Coordinate is:"); point2.display(); System.out.printf("\nThe line's length is:%.2f",distance); } }
第一题的总体难度不难,因为一个创建点的时候传入数据问题导致第一次提交没有满分。
在“点与线(类设计)”题目基础上,对题目的类设计进行重构,以实现继承与多态的技术性需求。
- 对题目中的点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();
其中,所有数值均保留两位小数,建议可用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:颜色值
输入样例1:
在这里给出一组输入。例如:
5
9.4
12.3
84
Red
输出样例1:
在这里给出相应的输出。例如:
(5.00,9.40)
(12.30,84.00)
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
The Plane's color is:Red
输入样例2:
在这里给出一组输入。例如:
5
9.4
12.3
845
Black
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
代码:
import java.text.DecimalFormat; import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner in=new Scanner(System.in); Point p1=new Point(); double x1=in.nextDouble(); double y1=in.nextDouble(); double x2=in.nextDouble(); double y2=in.nextDouble(); p1.setX(x1); p1.setY(y1); Point p2=new Point(); p2.setX(x2); p2.setY(y2); String color=in.next(); Line line=new Line(); line.setPoint1(p1); line.setPoint2(p2); line.setColor(color); Plane plane=new Plane(); plane.setColor(color); Element element=new Element() { @Override public void display() { } }; if ((x1<=0||x1>200)||(y1<=0||y1>200)||(x2<=0||x2>200)||(y2<=0||y2>200)) System.out.println("Wrong Format"); else{ element = p1;//起点Point element.display(); element = p2;//终点Point element.display(); element = line;//线段 element.display(); element = plane;//面 element.display(); } } } abstract class Element{ public abstract void display(); } class Point extends Element{ private double x;//横坐标 private double y;//纵坐标 public Point(double x, double y) { this.x = x; this.y = y; } public Point() { } 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 void display(){ DecimalFormat two=new DecimalFormat("0.00"); System.out.println("("+two.format(this.x)+","+two.format(this.y)+")"); } } class Line extends Element{ private Point point1 = new Point(); private Point point2 = new Point(); String color; public Line(Point point1, Point point2, String color) { this.point1 = point1; this.point2 = point2; this.color = color; } public Line() { } 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(Point p1,Point p2){ double a=p1.getX()-p2.getX(); double b=p1.getY()-p2.getY(); return Math.sqrt(a*a+b*b); } public void display(){ Line line=new Line(); DecimalFormat two=new DecimalFormat("0.00"); System.out.println("The line's color is:"+getColor()); 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(); System.out.println("The line's length is:" + two.format(line.getDistance(point1,point2))); } } class Plane extends Element{ private String color; public Plane(String color) { this.color = color; } public Plane() { } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void display(){ System.out.println("The Plane's color is:"+this.color); } }
第二题的难度比较适中
在“点与线(继承与多态)”题目基础上,对题目的类设计进行重构,增加容器类保存点、线、面对象,并对该容器进行相应增、删、遍历操作。
- 在原有类设计的基础上,增加一个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()
方法进行输出。
类图如下所示:
- 以下情况为无效作业
- 无法运行
- 设计不符合所给类图要求
- 未通过任何测试点测试
- 判定为抄袭
输入格式:
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超出合法范围,程序自动忽略该操作
输入样例:
在这里给出一组输入。例如:
1
3.4
5.6
2
4.4
8.0
0.98
23.888
Red
3
Black
1
9.8
7.5
3
Green
4
3
0
输出样例:
在这里给出相应的输出。例如:
(3.40,5.60)
The line's color is:Red
The line's begin point's Coordinate is:
(4.40,8.00)
The line's end point's Coordinate is:
(0.98,23.89)
The line's length is:16.25
(9.80,7.50)
The Plane's color is:Green
代码:
import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Scanner; public class Main{ public static void main(String []args) { Scanner in =new Scanner(System.in); int choice = in.nextInt(); ArrayList<Element> ad = new ArrayList<Element>(); while(choice != 0) { switch(choice) { case 1: Point point1= new Point(in.nextDouble(),in.nextDouble()); ad.add(point1); break; case 2: Point point3= new Point(in.nextDouble(),in.nextDouble()); Point point2= new Point(in.nextDouble(),in.nextDouble()); Line line = new Line(point3,point2,in.next()); ad.add(line); break; case 3: Plane plane=new Plane(in.next()); ad.add(plane); break; case 4: int index = in.nextInt(); ad.remove(index-1); } choice = in.nextInt(); } for (Element element : ad) { element.display(); } } } class Point extends Element{ private double x; private double y; public Point() { } public Point(double x, double y) { super(); 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 void display() { if((x<=0||x>200)||(y<=0)||(y>200)) { System.out.println("Wrong Format"); System.exit(0); }else { System.out.print("("); System.out.printf("%.2f,%.2f",x,y); System.out.println(")"); } } } class Line extends Element{ private Point point1; private Point point2; private String color; public Line() { } public Line(Point point1, Point point2, String color ) { super(); 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 static double getDistance(Point point1,Point point2) { double a; a=Math.sqrt((point1.getX()-point2.getX())*(point1.getX()-point2.getX())+(point1.getY()-point2.getY())*(point1.getY()-point2.getY())); return a; } public void display() { System.out.println("The line's color is:"+getColor()); System.out.println("The line's begin point's Coordinate is:"); System.out.print("("); System.out.printf("%.2f,%.2f",point1.getX(),point1.getY()); System.out.println(")"); System.out.println("The line's end point's Coordinate is:"); System.out.print("("); System.out.printf("%.2f,%.2f",point2.getX(),point2.getY()); System.out.println(")"); System.out.print("The line's length is:"); System.out.printf("%.2f\n",getDistance(point1,point2)); } } class Plane extends Element{ private String color; public Plane(String color) { super(); this.color = color; } public String getColor() { return color; } public void setColor(String color) { this.color=color; } public void display() { System.out.print("The Plane's color is:"+getColor()); } } class Element{ private double x; private double y; private Point point1; private Point point2; private String color; public void display() { System.out.print("("); System.out.printf("%.2f,%.2f",point1.getX(),point1.getY()); System.out.println(")"); System.out.print("("); System.out.printf("%.2f,%.2f",point2.getX(),point2.getY()); System.out.println(")"); System.out.println("The line's begin point's Coordinate is:"); System.out.print("("); System.out.printf("%.2f,%.2f",point1.getX(),point1.getY()); System.out.println(")"); System.out.println("The line's end point's Coordinate is:"); System.out.print("("); System.out.printf("%.2f,%.2f",point1.getX(),point1.getY()); System.out.println(")"); System.out.print("The line's length is:"); System.out.printf("%.2f",Line.getDistance(point1,point2)); } } class GeometryObject{ ArrayList<Element> ad = new ArrayList<Element>(); public GeometryObject() { super(); } public void add(Element element) { ad.add(element); } public void remove(int index) { if(index>0) ad.remove(index); } public ArrayList<Element> getList(){ return ad; } }
第三个题目没有全部完成,其实思路还是挺简单的。
(3)采坑心得:
1.题目集4 7-2 判断四边形是否成型时,用了斜率相等判断平行,但是在样例中会出现类似分母为零的情况,改用了x1y2=x2y1判断。
2.考虑相等问题的同时,需要判断是否需要考虑精度问题,有很多点是没加精度判断过不去的,精度不能设置太大也不能太小,合适就好,我的话精度1e-6或者1e-12,具体问题具体分析即可。
3.我们在拿到题目时,不要一股脑的想着如何去实现功能,我们可以先将最终要设计出来的代码进行功能分解,进而设计出多个不同功能的类,每个类再根据应有的功能写出相应的代码。
(4)改进建议:对相应题目的编码改进给出自己的见解,做到可持续改进
1.计算几何方面知识有所欠缺
2.我们可以参考一下别人代码的构造然后去自己模仿着写,不断改进自己的代码结构。
(5)总结:
这几次作业极大的提高了本人对面向对象编程的理解,且极大的提高了本人的代码能力。我对JAVA中常规类的使用习惯和构建方法更加清楚,可以很熟练地处理三角形、四边形、五边形其他类型的题目,也能通过较为合理的设计完成题目要求。