blog2

一、前言

这两次作业主要都是图形类设计的练习,对我来说难度很大,我都没有完成。主要的知识点是类的创建和初始化,this关键字,使用math类,创建对象,正则表达式等等。对我来说,第四五次作业题量适中,难度偏大,没有完成。期中考试时间紧凑题量有点大,难度适中,主要知识点是继承、多态、抽象类、重构、Arraylist、类的创建和初始化等等。

二、设计与分析

1、四边形

7-2 点线形系列4-凸四边形的计算
分数 70
作者 蔡轲
单位 南昌航空大学

用户输入一组选项和数据,进行与四边形有关的计算。
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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
 
代码长度限制
50 KB
时间限制
400 ms
内存限制
64 MB
源代码:

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {

Scanner in = new Scanner(System.in);
String s = in.nextLine();
InputData d = new InputData();
ParseInput.paseInput(s, d);
int choice = d.getChoice();
ArrayList ps = d.getPoints();
switch (choice) {
case 1:
handle1(ps);
break;
case 2:
handle2(ps);
break;
case 3:
handle3(ps);
break;
case 4:
handle4(ps);
break;
case 5:
handle5(ps);
break;
}

}


// 四边形、平行四边形
public static void handle1(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 4);
Quadrilateral t = new Quadrilateral(ps.get(0), ps.get(1), ps.get(2), ps.get(3));
System.out.println(t.isQuadrilateral() + " " + t.isParallelogram());

}

// 菱形、矩形、正方形
public static void handle2(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 4);
Quadrilateral t = new Quadrilateral(ps.get(0), ps.get(1), ps.get(2), ps.get(3));
if(!t.isQuadrilateral()) {
System.out.println("not a quadrilateral");
}
else
{
System.out.println(t.isLozenge() + " " + t.isEquilateralTriangle() + " " + t.isRightTriangle());
}
}

// 凹凸四边形
public static void handle3(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 4);
Quadrilateral t = new Quadrilateral(ps.get(0), ps.get(1), ps.get(2), ps.get(3));
if(!t.isQuadrilateral()) {
System.out.println("not a quadrilateral");
}
else
{
t.isBump();
}
}

public static void handle4(ArrayList<Point> ps) {
System.out.println("not a quadrilateral or triangle");
}
public static void handle5(ArrayList<Point> ps) {
System.out.println("in the triangle");
}
}
class Point {

public double x;
public double y;

public Point() {

}

public Point(double x,double y) {
this.x=x;
this.y=y;
}

/* 设置坐标x,将输入参数赋值给属性x */
public void setX(double x) {
this.x = x;
}

/* 设置坐标y,将输入参数赋值给属性y */
public void setY(double y) {
this.y = y;
}

/* 获取坐标x,返回属性x的值 */
public double getX() {
return x;
}

/* 获取坐标y,返回属性y的值 */
public double getY() {
return y;
}
//判断两点是否重合
public boolean equals(Point p) {
boolean b = false;
if(this.x==p.getX()&&this.y==p.getY()) {
b=true;
}
return b;
}
}

class InputData {

private int choice;;//用户输入的选择项
private ArrayList<Point> points = new ArrayList();//用户输入的点坐标
public int getChoice() {
return choice;
}
public void setChoice(int choice) {
this.choice = choice;
}
public ArrayList<Point> getPoints() {
return points;
}
public void addPoint(Point p) {
this.points.add(p);
}

}
class Quadrilateral{

private Point x;
private Point y;
private Point z;
private Point a;

public Quadrilateral(Point x, Point y, Point z,Point a) {
this.x = x;
this.y = y;
this.z = z;
this.a = a;
}

/* 判断x\y\z\a四个点的坐标是否能构成一个四边形 */
public boolean isQuadrilateral() {
double k1 = (this.x.getY() - this.y.getY()) / (this.x.getX() - this.y.getX());
double k2 = (this.x.getY() - this.z.getY()) / (this.x.getX() - this.z.getX());
double k3 = (this.x.getY() - this.a.getY()) / (this.x.getX() - this.a.getX());
double k4 = (this.y.getY() - this.z.getY()) / (this.y.getX() - this.z.getX());
double k5 = (this.y.getY() - this.a.getY()) / (this.y.getX() - this.a.getX());

if(k1==k2||k1==k3||k2==k3)
{
return false;
}
else
{
if(k4 == k5)
{
return false;

}
return true;

}
}
/* 判断是否平行四边形 */
public boolean isParallelogram() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
if(k1==k3&&k2==k4)
{
return true;
}
else
{
return false;
}
}

/* 获取四边形的面积,此处采用海伦公式
public double getArea() {

}
*/

/* 获取四边形的周长 */
public double getPerimeter() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
return Math.sqrt(k1)+Math.sqrt(k2)+Math.sqrt(k3)+Math.sqrt(k4);
}
/* 判断是否菱形 */
public boolean isLozenge() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
if(k1==k2&&k2==k3&&k3==k4) {
return true;
}
else
{
return false;
}
}
/* 判断是否矩形 */
public boolean isEquilateralTriangle() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
double k5 = (this.x.getX() - this.z.getX())*(this.x.getX() - this.z.getX())+(this.x.getY() - this.z.getY())*(this.x.getY() - this.z.getY());
double k6 = (this.y.getX() - this.a.getX())*(this.y.getX() - this.a.getX())+(this.y.getY() - this.a.getY())*(this.y.getY() - this.a.getY());
if(k1==k3&&k2==k4&&k5==k6) {
return true;
}
else
{
return false;
}
}

/* 判断是否正方形 */
public boolean isRightTriangle() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
double k5 = (this.x.getX() - this.z.getX())*(this.x.getX() - this.z.getX())+(this.x.getY() - this.z.getY())*(this.x.getY() - this.z.getY());
double k6 = (this.y.getX() - this.a.getX())*(this.y.getX() - this.a.getX())+(this.y.getY() - this.a.getY())*(this.y.getY() - this.a.getY());
if(k1==k2&&k2==k3&&k3==k4&&k5==k6) {
return true;
}
else
{
return false;
}
}

/* 判断是否凹四边形 还是凸四边形*/
public void isBump() {

double k1 = Math.sqrt(Math.pow(this.y.getX() - this.x.getX(), 2) + Math.pow(this.y.getY() - this.x.getY(), 2));
double k2 = Math.sqrt(Math.pow(this.z.getX() - this.a.getX(), 2) + Math.pow(this.z.getY() - this.a.getY(), 2));
double k3 = Math.sqrt(Math.pow(this.x.getX() - this.a.getX(), 2) + Math.pow(this.x.getY() - this.a.getY(), 2));
double k4 = Math.sqrt(Math.pow(this.y.getX() - this.z.getX(), 2) + Math.pow(this.y.getY() - this.z.getY(), 2));

double c =k1 + k2 + k3 + k4;
double s =0.5*Math.abs(x.x*y.y+y.x*z.y+z.x*a.y+a.x*x.y-y.x*x.y-z.x*y.y-a.x*z.y-x.x*a.y);

double t1 = (a.x-x.x)*(y.y-x.y)-(a.y-x.y)*(y.x-x.x);
double t2 = (x.x-y.x)*(z.y-y.y)-(x.y-y.y)*(z.x-y.x);
double t3 = (y.x-z.x)*(a.y-z.y)-(y.y-z.y)*(a.x-z.x);
double t4 = (z.x-a.x)*(x.y-a.y)-(z.y-a.y)*(x.x-a.x);
if( t1*t2*t3*t4 > 0)
{
System.out.printf("true %.3f %.1f",c,s);
System.exit(0);
}
else
{
System.out.printf("false %.3f %.1f",c,s);
System.exit(0);
}
}
/* 三个点的getter()和setter()方法 */
public Point getX() {
return x;
}

public void setX(Point x) {
this.x = x;
}

public Point getY() {
return y;
}

public void setY(Point y) {
this.y = y;
}

public Point getZ() {
return z;
}

public void setZ(Point z) {
this.z = z;
}
public Point getA() {
return a;
}

public void setA(Point z) {
this.z = a;
}
}
class PointInputError {

//判断从字符串中解析出的点的数量是否合格。
public static void wrongNumberOfPoints(ArrayList ps, int num) {
if (ps.size() != num) {
System.out.println("wrong number of points");
System.exit(0);
}
}
//判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序
public static void wrongPointFormat(String s) {
if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) {
System.out.println("Wrong Format");
System.exit(0);
}
}

// 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一
public static void wrongChoice(String s) {
if (!s.matches("[1-5]:.+")) {
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class ParseInput {

/*
* 输入:完整的输入字符串,包含选项和所有点的信息,格式:选项:x1,y1 x2,y2 .....xn,yn。选项只能是1-5
* 一个空InputData对象
* 处理:将输入字符串中的选项和点信息提取出来并设置到InputData对象中
* 输出:包含选项值和所有点的Point对象的InputData对象。
*/
public static void paseInput(String s, InputData d) {
PointInputError.wrongChoice(s);
d.setChoice(getChoice(s));
s = s.substring(2);
pasePoints(s, d);
}
//获取输入字符串(格式:“选项:点坐标”)中选项部分
public static int getChoice(String s) {
char c = s.charAt(0);
return c-48;
}

public static void pasePoints(String s, InputData d) {
String[] ss = s.split(" ");
if (ss.length == 0)
return;
for (int i = 0; i < ss.length; i++) {
d.addPoint(readPoint(ss[i]));
}
}

public static Point readPoint(String s) {
PointInputError.wrongPointFormat(s);
String[] ss = s.split(",");
double x = Double.parseDouble(ss[0]);
double y = Double.parseDouble(ss[1]);
// System.out.println("match");
return new Point(x, y);

}

}

踩坑心得:这题是第三次作业的升级版,需要封装四个类Point、Line、Triangle、Quadrilateral类,判断条件也更苛刻,在判断后四个点构成的是四边形,合法三角形上浪费了很多时间。

2、五边形-1

7-1 点线形系列5-凸五边形的计算-1
分数 50
作者 蔡轲
单位 南昌航空大学

用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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
代码长度限制
50 KB
时间限制
400 ms
内存限制
64 MB
源代码:

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {

Scanner in = new Scanner(System.in);
String s = in.nextLine();
InputData d = new InputData();
ParseInput.paseInput(s, d);
int choice = d.getChoice();
ArrayList ps = d.getPoints();
switch (choice) {
case 1:
handle1(ps);
break;
case 2:
handle2(ps);
break;
case 3:
handle3(ps);
break;
/*case 4:
handle4(ps);
break;
case 5:
handle5(ps);
break;
case 6:
handle6(ps);
break;*/
}
}
public static void handle1(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 5);
pentagon t = new pentagon(ps.get(0), ps.get(1), ps.get(2),ps.get(3),ps.get(4));
System.out.println(t.ispentagon());
}
public static void handle2(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 5);
pentagon t = new pentagon(ps.get(0), ps.get(1), ps.get(2),ps.get(3),ps.get(4));
if(!t.ispentagon()) {
System.out.println("not a pentagon");
}
else if(!t.istupengtagon()) {
System.out.println(t.istupengtagon());
}else {
System.out.println(t.istupengtagon()+" "+t.getPerimeter()+" "+t.getArea());
}
}
public static void handle3(ArrayList<Point> ps) {
System.out.println("points coincide");
}
}

class Point {
public double x;
public double y;

public Point() {

}

public Point(double x,double y) {
this.x=x;
this.y=y;
}

/* 设置坐标x,将输入参数赋值给属性x */
public void setX(double x) {
this.x = x;
}

/* 设置坐标y,将输入参数赋值给属性y */
public void setY(double y) {
this.y = y;
}

/* 获取坐标x,返回属性x的值 */
public double getX() {
return x;
}

/* 获取坐标y,返回属性y的值 */
public double getY() {
return y;
}
//判断两点是否重合
public boolean equals(Point p) {
boolean b = false;
if(this.x==p.getX()&&this.y==p.getY()) {
b=true;
}
return b;
}

/* 计算当前点和输入点p之间的距离 */
public double getDistance(Point p) {
return Math.sqrt((p.getX()-this.x)*(p.getX()-this.x)+(p.getY()-this.y)*(p.getY()-this.y));
}

}
class Line {
private Point p1;//线上的第一个点
private Point p2;//线上的第二个点


public Line(double x1, double y1, double x2, double y2) {
Point p1 = new Point(x1, y1);
Point p2 = new Point(x2, y2);
LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出
this.p1 = p1;
this.p2 = p2;
}

public Line(Point p1, Point p2) {
LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出
this.p1 = p1;
this.p2 = p2;
}

/* 获取线条的斜率 */
public Double getSlope() {
// (x1-x2=0)注意考虑斜率不存在即返回double类型无穷大"Infinite"
return (p2.getY() - p1.getY()) / (p2.getX() - p1.getX());
}
public double detdis() {
return Math.sqrt((p1.getX()-p2.getX())*(p1.getX()-p2.getX())+(p1.getY()-p2.getY())*(p1.getY()-p2.getY()));
}
/* 判断x是否在线上 */
public boolean isOnline(Point x) {
//System.out.println("isOnline");
//System.out.println(p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y + " ");

// 点重合
if ((x.getX() == p1.getX() && x.getY() == p1.getY()) || (x.getX() == p2.getX() && x.getY() == p2.getY())) {
return true;
}
Line l = new Line(p1, x);
if (l.getSlope().isInfinite() && this.getSlope().isInfinite()) {
return true;
}

/*
* if (l.getSlope().isInfinite() || this.getSlope().isInfinite()) { return
* false; }
*/

// 此点与线上任意一点构成的线的斜率相等则此点在线上
double b1 = l.getSlope(), b2 = this.getSlope();
//System.out.println(b1 + " " + b2 + " " + (b1- b2) + " " + (Math.abs(b1 - b2) < 0.00000000001));

return Math.abs(b1 - b2) < 0.00000000001;// b1==b2;
}

/* 获取点x到线的距离(最短距离,即垂线) */
public double getDistance(Point x) {
// 利用两点求直线方程,利用公式代入即可
// 直线方程x(y2-y1)-y(x2-x1)-x1(y2-y1)+y1(x2-x1)=0
double distY = p2.getY() - p1.getY();
double distX = p2.getX() - p1.getX();
return Math.abs(x.getX() * distY - x.getY() * distX - p1.getX() * distY + p1.getY() * distX)
/ p1.getDistance(p2);
}

/* 判断x是否在线上且在两点之间 */
public boolean isBetween(Point x) {
//System.out.println("isBetween" + " " + this.p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y);
if (!this.isOnline(x)) {
return false;
}
// 与端点重合,认为不在在两点之间,
if (x.equals(p1) || x.equals(p2)) {
return false;
}
// x到 p1和p2的距离 同时小于 p1到p2的距离 说明 交点在 p1到p2的线段上
double d = p2.getDistance(p1);
boolean b = x.getDistance(p2) < d && x.getDistance(p1) < d;
//System.out.println("isBetween" + b);
return b;
}

/* 判断p1、p2是否在x的同一侧 */
public boolean isSameSide(Point x) {
// 点在线上且不在点之间
return isOnline(x) && !isBetween(x);
}

/* 获取p1、p2之间的中点 */
public Point getMiddlePoint() {
Point p = new Point();
p.setX((p1.getX() + p2.getX()) / 2);
p.setY((p1.getY() + p2.getY()) / 2);
return p;
}

/* 获取线段的第一个坐标点 */
public Point getPointA() {
return p1;
}

/* 获取线段的第二个坐标点 */
public Point getPointB() {
return p2;
}

/* 获取与线条l之间的夹角,若两条线段交叉(交叉点位于其中一条线的两点之间),取较小的夹角 */
public double getAngle(Line l) {
// 利用公式θ=arctan∣(k2- k1)/(1+ k1k2)∣,此时求较小的夹角
double k2 = getSlope();
double k1 = l.getSlope();
return (double) (Math.atan(Math.abs((k2 - k1) / (1 + k1 * k2))) * 180.0 / Math.PI);// 返回值为角度
}

// 是否平行,平行返回true,否则false。
public boolean isParallel(Line l) {
Double b1 = this.getSlope();
Double b2 = l.getSlope();
if ((b1.isInfinite()) && (b2.isInfinite())) {
return true;
} else {
return (this.getSlope().doubleValue() == l.getSlope().doubleValue());
}
}

// 两条线是否重合,重合返回true,否则false。

public boolean isCoincide(Line l) {
if (!this.isParallel(l)) {
return false;
}
if (this.isOnline(l.p1)) {
return true;
}
return false;
}
}
class InputData {
private int choice;;//用户输入的选择项
private ArrayList<Point> points = new ArrayList();//用户输入的点坐标
public int getChoice() {
return choice;
}
public void setChoice(int choice) {
this.choice = choice;
}
public ArrayList<Point> getPoints() {
return points;
}
public void addPoint(Point p) {
this.points.add(p);
}

}
//用于处理线条相关功能中出现的异常提示。
class LineInputError {

// 直线的两点重合的错误判断和提示。
public static void pointsCoincideError(Point p1, Point p2) {
if ((p1.getX() == p2.getX()) && p1.getY() == p2.getY()) {
System.out.println("points coincide");
System.exit(0);
}
}


}
class OutFormat {
//按要求格式化实数的输出。
public static Double doubleFormat(double b) {
DecimalFormat df = new DecimalFormat("#.000000");
Double output = Double.valueOf(df.format(b));
return output;
}
}
class ParseInput {
/*
* 输入:完整的输入字符串,包含选项和所有点的信息,格式:选项:x1,y1 x2,y2 .....xn,yn。选项只能是1-5
* 一个空InputData对象
* 处理:将输入字符串中的选项和点信息提取出来并设置到InputData对象中
* 输出:包含选项值和所有点的Point对象的InputData对象。
*/
public static void paseInput(String s, InputData d) {
PointInputError.wrongChoice(s);
d.setChoice(getChoice(s));
s = s.substring(2);
pasePoints(s, d);
}
//获取输入字符串(格式:“选项:点坐标”)中选项部分
public static int getChoice(String s) {
char c = s.charAt(0);
return c-48;
}

/*
* 输入:一个字符串,包含所有点的信息,格式:x1,y1 x2,y2 .....xn,yn
* 一个空InputData对象
* 输出:所有点的Point对象
*/

public static void pasePoints(String s, InputData d) {
String[] ss = s.split(" ");
if (ss.length == 0)
return;
for (int i = 0; i < ss.length; i++) {
d.addPoint(readPoint(ss[i]));
}
}

/*
* 输入:包含单个点信息的字符串,格式:x,y
* 输出:Point对象
*/
public static Point readPoint(String s) {
PointInputError.wrongPointFormat(s);
String[] ss = s.split(",");
double x = Double.parseDouble(ss[0]);
double y = Double.parseDouble(ss[1]);
// System.out.println("match");
return new Point(x, y);

}
}
class PointInputError {
//判断从字符串中解析出的点的数量是否合格。
public static void wrongNumberOfPoints(ArrayList ps, int num) {
if (ps.size() != num) {
System.out.println("wrong number of points");
System.exit(0);
}
}
//判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序
public static void wrongPointFormat(String s) {
if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) {
System.out.println("Wrong Format");
System.exit(0);
}
}

// 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一
public static void wrongChoice(String s) {
if (!s.matches("[1-6]:.+")) {
System.out.println("Wrong Format");
System.exit(0);
}
}

}
class pentagon{
private Point a;
private Point b;
private Point c;
private Point d;
private Point e;
/*private Line l1;
private Line l2;
private Line l3;
private Line l4;
private Line l5;*/

public pentagon(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.l1=new Line( a, b);
this.l2=new Line( b, c);
this.l3=new Line( c, d);
this.l4=new Line( d, e);
this.l5=new Line( e, a);*/
}
public boolean ispentagon(){//是否为五边形
double k1=(this.a.getY()-this.b.getY())/(this.a.getX()-this.b.getX());
double k2=(this.a.getY()-this.c.getY())/(this.a.getX()-this.c.getX());
double k3=(this.a.getY()-this.d.getY())/(this.a.getX()-this.d.getX());
double k4=(this.a.getY()-this.e.getY())/(this.a.getX()-this.e.getX());
double k5=(this.b.getY()-this.c.getY())/(this.b.getX()-this.c.getX());
double k6=(this.b.getY()-this.d.getY())/(this.b.getX()-this.d.getX());
double k7=(this.b.getY()-this.e.getY())/(this.b.getX()-this.e.getX());
double k8=(this.c.getY()-this.d.getY())/(this.c.getX()-this.d.getX());
double k9=(this.c.getY()-this.e.getY())/(this.c.getX()-this.e.getX());
//double k10=(this.d.getY()-this.e.getY())/(this.d.getX()-this.e.getX());
if(k1!=k2&&k1!=k3&&k1!=k4&&k2!=k3&&k2!=k4&&k3!=k4&&k5!=k6&&k5!=k7&&k6!=k7&&k8!=k9) {
return true;
}
else
return false;
}
public boolean istupengtagon() {//是否为凸五边形
double k1=(this.a.getY()-this.b.getY())/(this.a.getX()-this.b.getX());
double k2=(this.a.getY()-this.c.getY())/(this.a.getX()-this.c.getX());
double k3=(this.a.getY()-this.d.getY())/(this.a.getX()-this.d.getX());
double k4=(this.a.getY()-this.e.getY())/(this.a.getX()-this.e.getX());
double k5=(this.b.getY()-this.c.getY())/(this.b.getX()-this.c.getX());
double k6=(this.b.getY()-this.d.getY())/(this.b.getX()-this.d.getX());
double k7=(this.b.getY()-this.e.getY())/(this.b.getX()-this.e.getX());
double k8=(this.c.getY()-this.d.getY())/(this.c.getX()-this.d.getX());
double k9=(this.c.getY()-this.e.getY())/(this.c.getX()-this.e.getX());
double k10=(this.d.getY()-this.e.getY())/(this.d.getX()-this.e.getX());
double angle1 =(Math.atan(Math.abs((k4 - k1) / (1 + k1 * k4))) * 180.0 / Math.PI);
double angle2 =(Math.atan(Math.abs((k5 - k1) / (1 + k1 * k5))) * 180.0 / Math.PI);
double angle3 =(Math.atan(Math.abs((k5 - k8) / (1 + k5 * k8))) * 180.0 / Math.PI);
double angle4 =(Math.atan(Math.abs((k8 - k10) / (1 + k8 * k10))) * 180.0 / Math.PI);
double angle5 =(Math.atan(Math.abs((k4 - k10) / (1 + k4 * k10))) * 180.0 / Math.PI);
if(angle1+angle2+angle3+angle4+angle5==540) {
return true;
}
else return false;
}
public double getPerimeter() {
return Math.sqrt((a.getX()-b.getX())*(a.getX()-b.getX())+(a.getY()-b.getY())*(a.getY()-b.getY()))+Math.sqrt((b.getX()-c.getX())*(b.getX()-c.getX())+(b.getY()-c.getY())*(b.getY()-c.getY()))+Math.sqrt((c.getX()-d.getX())*(c.getX()-d.getX())+(c.getY()-d.getY())*(c.getY()-d.getY()))+Math.sqrt((d.getX()-e.getX())*(d.getX()-e.getX())+(d.getY()-e.getY())*(d.getY()-e.getY()))+Math.sqrt((e.getX()-a.getX())*(e.getX()-a.getX())+(e.getY()-a.getY())*(e.getY()-a.getY()));
}
public double getArea() {
double d1=Math.abs(b.getX() * (a.getY()-e.getY()) - b.getY() * (a.getX()-e.getX()) - a.getX() * (a.getY()-e.getY()) + a.getY() * (a.getX()-e.getX()))
/Math.sqrt((a.getX()-e.getX())*(a.getX()-e.getX())+(a.getY()-e.getY())*(a.getY()-e.getY()));//b点到ae线上的距离
double d2=Math.abs(e.getX() * (b.getY()-c.getY()) - e.getY() * (b.getX()-c.getX()) - b.getX() * (b.getY()-c.getY()) + b.getY() * (b.getX()-c.getX()))
/Math.sqrt((b.getX()-c.getX())*(b.getX()-c.getX())+(b.getY()-c.getY())*(b.getY()-c.getY()));//e点到bc线上的距离
double d3=Math.abs(d.getX() * (c.getY()-e.getY()) - d.getY() * (c.getX()-e.getX()) - c.getX() * (c.getY()-e.getY()) + c.getY() * (c.getX()-e.getX()))
/Math.sqrt((e.getX()-c.getX())*(e.getX()-c.getX())+(e.getY()-c.getY())*(e.getY()-c.getY()));;//d点到ce线上的距离
return (d1*Math.sqrt((a.getX()-e.getX())*(a.getX()-e.getX())+(a.getY()-e.getY())*(a.getY()-e.getY()))+d2*Math.sqrt((b.getX()-c.getX())*(b.getX()-c.getX())+(b.getY()-c.getY())*(b.getY()-c.getY()))+d3*Math.abs((e.getX()-c.getX())*(e.getX()-c.getX())+(e.getY()-c.getY())*(e.getY()-c.getY())))/2;
}
}

3、五边形-2
7-2 点线形系列5-凸五边形的计算-2
分数 50
作者 蔡轲
单位 南昌航空大学

用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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
代码长度限制
50 KB
时间限制
400 ms
内存限制
64 MB
源代码:

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {

Scanner in = new Scanner(System.in);
String s = in.nextLine();
InputData d = new InputData();
ParseInput.paseInput(s, d);
int choice = d.getChoice();
ArrayList ps = d.getPoints();
switch (choice) {
case 1:
handle1(ps);
break;
case 2:
handle2(ps);
break;
case 3:
handle3(ps);
break;
/*case 4:
handle4(ps);
break;
case 5:
handle5(ps);
break;
case 6:
handle6(ps);
break;*/
}
}
public static void handle1(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 5);
pentagon t = new pentagon(ps.get(0), ps.get(1), ps.get(2),ps.get(3),ps.get(4));
System.out.println(t.ispentagon());
}
public static void handle2(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 5);
pentagon t = new pentagon(ps.get(0), ps.get(1), ps.get(2),ps.get(3),ps.get(4));
if(!t.ispentagon()) {
System.out.println("not a pentagon");
}
else if(!t.istupengtagon()) {
System.out.println(t.istupengtagon());
}else {
System.out.println(t.istupengtagon()+" "+t.getPerimeter()+" "+t.getArea());
}
}
public static void handle3(ArrayList<Point> ps) {
System.out.println("points coincide");
}
}

class Point {
public double x;
public double y;

public Point() {

}

public Point(double x,double y) {
this.x=x;
this.y=y;
}

/* 设置坐标x,将输入参数赋值给属性x */
public void setX(double x) {
this.x = x;
}

/* 设置坐标y,将输入参数赋值给属性y */
public void setY(double y) {
this.y = y;
}

/* 获取坐标x,返回属性x的值 */
public double getX() {
return x;
}

/* 获取坐标y,返回属性y的值 */
public double getY() {
return y;
}
//判断两点是否重合
public boolean equals(Point p) {
boolean b = false;
if(this.x==p.getX()&&this.y==p.getY()) {
b=true;
}
return b;
}

/* 计算当前点和输入点p之间的距离 */
public double getDistance(Point p) {
return Math.sqrt((p.getX()-this.x)*(p.getX()-this.x)+(p.getY()-this.y)*(p.getY()-this.y));
}

}
class Line {
private Point p1;//线上的第一个点
private Point p2;//线上的第二个点


public Line(double x1, double y1, double x2, double y2) {
Point p1 = new Point(x1, y1);
Point p2 = new Point(x2, y2);
LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出
this.p1 = p1;
this.p2 = p2;
}

public Line(Point p1, Point p2) {
LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出
this.p1 = p1;
this.p2 = p2;
}

/* 获取线条的斜率 */
public Double getSlope() {
// (x1-x2=0)注意考虑斜率不存在即返回double类型无穷大"Infinite"
return (p2.getY() - p1.getY()) / (p2.getX() - p1.getX());
}
public double detdis() {
return Math.sqrt((p1.getX()-p2.getX())*(p1.getX()-p2.getX())+(p1.getY()-p2.getY())*(p1.getY()-p2.getY()));
}
/* 判断x是否在线上 */
public boolean isOnline(Point x) {
//System.out.println("isOnline");
//System.out.println(p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y + " ");

// 点重合
if ((x.getX() == p1.getX() && x.getY() == p1.getY()) || (x.getX() == p2.getX() && x.getY() == p2.getY())) {
return true;
}
Line l = new Line(p1, x);
if (l.getSlope().isInfinite() && this.getSlope().isInfinite()) {
return true;
}

/*
* if (l.getSlope().isInfinite() || this.getSlope().isInfinite()) { return
* false; }
*/

// 此点与线上任意一点构成的线的斜率相等则此点在线上
double b1 = l.getSlope(), b2 = this.getSlope();
//System.out.println(b1 + " " + b2 + " " + (b1- b2) + " " + (Math.abs(b1 - b2) < 0.00000000001));

return Math.abs(b1 - b2) < 0.00000000001;// b1==b2;
}

/* 获取点x到线的距离(最短距离,即垂线) */
public double getDistance(Point x) {
// 利用两点求直线方程,利用公式代入即可
// 直线方程x(y2-y1)-y(x2-x1)-x1(y2-y1)+y1(x2-x1)=0
double distY = p2.getY() - p1.getY();
double distX = p2.getX() - p1.getX();
return Math.abs(x.getX() * distY - x.getY() * distX - p1.getX() * distY + p1.getY() * distX)
/ p1.getDistance(p2);
}

/* 判断x是否在线上且在两点之间 */
public boolean isBetween(Point x) {
//System.out.println("isBetween" + " " + this.p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y);
if (!this.isOnline(x)) {
return false;
}
// 与端点重合,认为不在在两点之间,
if (x.equals(p1) || x.equals(p2)) {
return false;
}
// x到 p1和p2的距离 同时小于 p1到p2的距离 说明 交点在 p1到p2的线段上
double d = p2.getDistance(p1);
boolean b = x.getDistance(p2) < d && x.getDistance(p1) < d;
//System.out.println("isBetween" + b);
return b;
}

/* 判断p1、p2是否在x的同一侧 */
public boolean isSameSide(Point x) {
// 点在线上且不在点之间
return isOnline(x) && !isBetween(x);
}

/* 获取p1、p2之间的中点 */
public Point getMiddlePoint() {
Point p = new Point();
p.setX((p1.getX() + p2.getX()) / 2);
p.setY((p1.getY() + p2.getY()) / 2);
return p;
}

/* 获取线段的第一个坐标点 */
public Point getPointA() {
return p1;
}

/* 获取线段的第二个坐标点 */
public Point getPointB() {
return p2;
}

/* 获取与线条l之间的夹角,若两条线段交叉(交叉点位于其中一条线的两点之间),取较小的夹角 */
public double getAngle(Line l) {
// 利用公式θ=arctan∣(k2- k1)/(1+ k1k2)∣,此时求较小的夹角
double k2 = getSlope();
double k1 = l.getSlope();
return (double) (Math.atan(Math.abs((k2 - k1) / (1 + k1 * k2))) * 180.0 / Math.PI);// 返回值为角度
}

// 是否平行,平行返回true,否则false。
public boolean isParallel(Line l) {
Double b1 = this.getSlope();
Double b2 = l.getSlope();
if ((b1.isInfinite()) && (b2.isInfinite())) {
return true;
} else {
return (this.getSlope().doubleValue() == l.getSlope().doubleValue());
}
}

// 两条线是否重合,重合返回true,否则false。

public boolean isCoincide(Line l) {
if (!this.isParallel(l)) {
return false;
}
if (this.isOnline(l.p1)) {
return true;
}
return false;
}
}
class InputData {
private int choice;;//用户输入的选择项
private ArrayList<Point> points = new ArrayList();//用户输入的点坐标
public int getChoice() {
return choice;
}
public void setChoice(int choice) {
this.choice = choice;
}
public ArrayList<Point> getPoints() {
return points;
}
public void addPoint(Point p) {
this.points.add(p);
}

}
//用于处理线条相关功能中出现的异常提示。
class LineInputError {

// 直线的两点重合的错误判断和提示。
public static void pointsCoincideError(Point p1, Point p2) {
if ((p1.getX() == p2.getX()) && p1.getY() == p2.getY()) {
System.out.println("points coincide");
System.exit(0);
}
}


}
class OutFormat {
//按要求格式化实数的输出。
public static Double doubleFormat(double b) {
DecimalFormat df = new DecimalFormat("#.000000");
Double output = Double.valueOf(df.format(b));
return output;
}
}
class ParseInput {
/*
* 输入:完整的输入字符串,包含选项和所有点的信息,格式:选项:x1,y1 x2,y2 .....xn,yn。选项只能是1-5
* 一个空InputData对象
* 处理:将输入字符串中的选项和点信息提取出来并设置到InputData对象中
* 输出:包含选项值和所有点的Point对象的InputData对象。
*/
public static void paseInput(String s, InputData d) {
PointInputError.wrongChoice(s);
d.setChoice(getChoice(s));
s = s.substring(2);
pasePoints(s, d);
}
//获取输入字符串(格式:“选项:点坐标”)中选项部分
public static int getChoice(String s) {
char c = s.charAt(0);
return c-48;
}

/*
* 输入:一个字符串,包含所有点的信息,格式:x1,y1 x2,y2 .....xn,yn
* 一个空InputData对象
* 输出:所有点的Point对象
*/

public static void pasePoints(String s, InputData d) {
String[] ss = s.split(" ");
if (ss.length == 0)
return;
for (int i = 0; i < ss.length; i++) {
d.addPoint(readPoint(ss[i]));
}
}

/*
* 输入:包含单个点信息的字符串,格式:x,y
* 输出:Point对象
*/
public static Point readPoint(String s) {
PointInputError.wrongPointFormat(s);
String[] ss = s.split(",");
double x = Double.parseDouble(ss[0]);
double y = Double.parseDouble(ss[1]);
// System.out.println("match");
return new Point(x, y);

}
}
class PointInputError {
//判断从字符串中解析出的点的数量是否合格。
public static void wrongNumberOfPoints(ArrayList ps, int num) {
if (ps.size() != num) {
System.out.println("wrong number of points");
System.exit(0);
}
}
//判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序
public static void wrongPointFormat(String s) {
if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) {
System.out.println("Wrong Format");
System.exit(0);
}
}

// 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一
public static void wrongChoice(String s) {
if (!s.matches("[1-6]:.+")) {
System.out.println("Wrong Format");
System.exit(0);
}
}

}
class pentagon{
private Point a;
private Point b;
private Point c;
private Point d;
private Point e;
/*private Line l1;
private Line l2;
private Line l3;
private Line l4;
private Line l5;*/

public pentagon(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.l1=new Line( a, b);
this.l2=new Line( b, c);
this.l3=new Line( c, d);
this.l4=new Line( d, e);
this.l5=new Line( e, a);*/
}
public boolean ispentagon(){//是否为五边形
double k1=(this.a.getY()-this.b.getY())/(this.a.getX()-this.b.getX());
double k2=(this.a.getY()-this.c.getY())/(this.a.getX()-this.c.getX());
double k3=(this.a.getY()-this.d.getY())/(this.a.getX()-this.d.getX());
double k4=(this.a.getY()-this.e.getY())/(this.a.getX()-this.e.getX());
double k5=(this.b.getY()-this.c.getY())/(this.b.getX()-this.c.getX());
double k6=(this.b.getY()-this.d.getY())/(this.b.getX()-this.d.getX());
double k7=(this.b.getY()-this.e.getY())/(this.b.getX()-this.e.getX());
double k8=(this.c.getY()-this.d.getY())/(this.c.getX()-this.d.getX());
double k9=(this.c.getY()-this.e.getY())/(this.c.getX()-this.e.getX());
//double k10=(this.d.getY()-this.e.getY())/(this.d.getX()-this.e.getX());
if(k1!=k2&&k1!=k3&&k1!=k4&&k2!=k3&&k2!=k4&&k3!=k4&&k5!=k6&&k5!=k7&&k6!=k7&&k8!=k9) {
return true;
}
else
return false;
}
public boolean istupengtagon() {//是否为凸五边形
double k1=(this.a.getY()-this.b.getY())/(this.a.getX()-this.b.getX());
double k2=(this.a.getY()-this.c.getY())/(this.a.getX()-this.c.getX());
double k3=(this.a.getY()-this.d.getY())/(this.a.getX()-this.d.getX());
double k4=(this.a.getY()-this.e.getY())/(this.a.getX()-this.e.getX());
double k5=(this.b.getY()-this.c.getY())/(this.b.getX()-this.c.getX());
double k6=(this.b.getY()-this.d.getY())/(this.b.getX()-this.d.getX());
double k7=(this.b.getY()-this.e.getY())/(this.b.getX()-this.e.getX());
double k8=(this.c.getY()-this.d.getY())/(this.c.getX()-this.d.getX());
double k9=(this.c.getY()-this.e.getY())/(this.c.getX()-this.e.getX());
double k10=(this.d.getY()-this.e.getY())/(this.d.getX()-this.e.getX());
double angle1 =(Math.atan(Math.abs((k4 - k1) / (1 + k1 * k4))) * 180.0 / Math.PI);
double angle2 =(Math.atan(Math.abs((k5 - k1) / (1 + k1 * k5))) * 180.0 / Math.PI);
double angle3 =(Math.atan(Math.abs((k5 - k8) / (1 + k5 * k8))) * 180.0 / Math.PI);
double angle4 =(Math.atan(Math.abs((k8 - k10) / (1 + k8 * k10))) * 180.0 / Math.PI);
double angle5 =(Math.atan(Math.abs((k4 - k10) / (1 + k4 * k10))) * 180.0 / Math.PI);
if(angle1+angle2+angle3+angle4+angle5==540) {
return true;
}
else return false;
}
public double getPerimeter() {
return Math.sqrt((a.getX()-b.getX())*(a.getX()-b.getX())+(a.getY()-b.getY())*(a.getY()-b.getY()))+Math.sqrt((b.getX()-c.getX())*(b.getX()-c.getX())+(b.getY()-c.getY())*(b.getY()-c.getY()))+Math.sqrt((c.getX()-d.getX())*(c.getX()-d.getX())+(c.getY()-d.getY())*(c.getY()-d.getY()))+Math.sqrt((d.getX()-e.getX())*(d.getX()-e.getX())+(d.getY()-e.getY())*(d.getY()-e.getY()))+Math.sqrt((e.getX()-a.getX())*(e.getX()-a.getX())+(e.getY()-a.getY())*(e.getY()-a.getY()));
}
public double getArea() {
double d1=Math.abs(b.getX() * (a.getY()-e.getY()) - b.getY() * (a.getX()-e.getX()) - a.getX() * (a.getY()-e.getY()) + a.getY() * (a.getX()-e.getX()))
/Math.sqrt((a.getX()-e.getX())*(a.getX()-e.getX())+(a.getY()-e.getY())*(a.getY()-e.getY()));//b点到ae线上的距离
double d2=Math.abs(e.getX() * (b.getY()-c.getY()) - e.getY() * (b.getX()-c.getX()) - b.getX() * (b.getY()-c.getY()) + b.getY() * (b.getX()-c.getX()))
/Math.sqrt((b.getX()-c.getX())*(b.getX()-c.getX())+(b.getY()-c.getY())*(b.getY()-c.getY()));//e点到bc线上的距离
double d3=Math.abs(d.getX() * (c.getY()-e.getY()) - d.getY() * (c.getX()-e.getX()) - c.getX() * (c.getY()-e.getY()) + c.getY() * (c.getX()-e.getX()))
/Math.sqrt((e.getX()-c.getX())*(e.getX()-c.getX())+(e.getY()-c.getY())*(e.getY()-c.getY()));;//d点到ce线上的距离
return (d1*Math.sqrt((a.getX()-e.getX())*(a.getX()-e.getX())+(a.getY()-e.getY())*(a.getY()-e.getY()))+d2*Math.sqrt((b.getX()-c.getX())*(b.getX()-c.getX())+(b.getY()-c.getY())*(b.getY()-c.getY()))+d3*Math.abs((e.getX()-c.getX())*(e.getX()-c.getX())+(e.getY()-c.getY())*(e.getY()-c.getY())))/2;
}
}

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

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

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

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

      设计类图如下图所示。
    
     

1641304523(1).jpg

** 题目要求:在主方法中定义一条线段对象,从键盘输入该线段的起点坐标与终点坐标以及颜色,然后调用该线段的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
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
源代码:
踩坑心得:第一题其实就是看类图写代码,题目难度不大,需要补全其中方法和属性,理清楚图中的符号和箭头和每个类的关系就可。
改进建议:无
5、期中考-2
7-2 点线面问题重构(继承与多态)
分数 40
作者 段喜龙
单位 南昌航空大学

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

  • 对题目中的点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();
    
     
    类结构如下图所示。

1641340607(1).jpg

其中,所有数值均保留两位小数,建议可用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
 
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
源代码:
踩坑心得:第二题是对第一题的再拓展,本题需要创建应该抽象类Element,并运用display()方法,相较上题做一个改进,实现多态特性。
改进建议:无
6、期中考-3
7-3 点线面问题再重构(容器类)
分数 40
作者 段喜龙
单位 南昌航空大学

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

  • 在原有类设计的基础上,增加一个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()方法进行输出。
    类图如下所示:

classdiagram.jpg

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

输入格式:

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
 
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
源代码:

import java.util.Scanner;
public class Main{
public static void main(String args[]){
Scanner s=new Scanner(System.in);
double x1,y1,x2,y2;
String color;
x1=s.nextDouble();
y1=s.nextDouble();
x2=s.nextDouble();
y2=s.nextDouble();
color=s.nextLine();
if(x1<0||x1>200||x2<0||x2>200||y1<0||y1>200||y2<0||y2>200){
System.out.println("Wrong Format");
System.exit(0);
}

color=s.nextLine();
Point p1=new Point(x1,y1);
Point p2=new Point(x2,y2);
Line l1=new Line(p1,p2,color);
l1.display();
}
}


/*class point{
private double x;
private double y;
point(){
this.x=0;
this.y=0;
}
point(double x,double y){
this.x=x;
this.y=y;
}
}
public double getX(double x){
return x;
}
public double setX(double x){
this.x=x;
}
public double getY(double y){
return y;}
public double setY(double y){
this.y=y;
}
*/


class Point{
private double x;
private double y;
Point(){

}
Point(double x,double y){
setX(x);
setY(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.println("("+String.format("%.2f",getX( ))+","+String.format("%.2f",getY())+")");
}
}

class Line{
Point point1;
Point point2;
String color;

Line(){

}
Line(Point p1,Point p2,String color){
setPoint1(p1);
setPoint2(p2);
setColor(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() {
return Math.sqrt(Math.pow((getPoint2().getY() - getPoint1().getY()),2) + Math.pow((getPoint2().getX() - getPoint1().getX()), 2));
}
public void display(){
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:"+String.format("%.2f", getDistance()));
}
}

改进建议:由于时间不够我直接使用了前面的代码,过了几个测试点。
 

三、总结

通过这两次的PTA作业和期中考试,我深刻的认识到自己太多知识点应用太不熟练了,如:Arraylist的使用、包装类、多态、容器类的使用等等。在之后的学习中,我会多看他人优秀的代码,改进我的代码,化繁为简介。

posted @ 2022-10-29 21:20  Cornfield  阅读(52)  评论(0)    收藏  举报