太爽了
甚至还现学了叉积判断线段是否相交和求面积的方法
先给出我的代码:
#include <iostream>
#include <vector>
#include <iomanip>
#include <cmath>using namespace std;//下面需要补充多个类的声明及实现代码
const double EPS = 1e-6;
struct Point{double x, y;Point(double x, double y):x(x), y(y){}
};class Quadrilateral{
public:Quadrilateral(){}Quadrilateral(vector<Point> &vertices):p(vertices){}double getArea();double getPerimeter();bool verify();
protected:vector<Point> p;//四边形的四个顶点,从任一顶点出发按顺序存放
};class Parallelogram:protected Quadrilateral{
public:Parallelogram(){}Parallelogram(vector<Point> &vertices){Quadrilateral::p = vertices;}double getArea();double getPerimeter();bool verify();
};class Rectangle:protected Parallelogram{
public:Rectangle(){}Rectangle(vector<Point> &vertices){Quadrilateral::p = vertices;}double getArea();double getPerimeter();bool verify();
};bool Quadrilateral::verify(){{double x1 = p[2].x - p[0].x, y1 = p[2].y - p[0].y;double x2 = p[1].x - p[0].x, y2 = p[1].y - p[0].y;double x3 = p[3].x - p[0].x, y3 = p[3].y - p[0].y;if((x1 * y2 - x2 * y1) * (x1 * y3 - x3 * y1) >= 0) return false;}{double x1 = p[3].x - p[1].x, y1 = p[3].y - p[1].y;double x2 = p[0].x - p[1].x, y2 = p[0].y - p[1].y;double x3 = p[2].x - p[1].x, y3 = p[2].y - p[1].y;if((x1 * y2 - x2 * y1) * (x1 * y3 - x3 * y1) >= 0) return false;}return true;
}
double Quadrilateral::getArea(){if(verify()){double S1 = 0.5 * fabs((p[1].x - p[0].x) * (p[2].y - p[0].y) - (p[1].y - p[0].y) * (p[2].x - p[0].x));double S2 = 0.5 * fabs((p[3].x - p[0].x) * (p[2].y - p[0].y) - (p[3].y - p[0].y) * (p[2].x - p[0].x));return S1 + S2;}else return 0.0;
}
double Quadrilateral::getPerimeter(){if(verify()){double l1 = sqrt(pow(p[1].x - p[0].x, 2.0) + pow(p[1].y - p[0].y, 2.0));double l2 = sqrt(pow(p[2].x - p[1].x, 2.0) + pow(p[2].y - p[1].y, 2.0));double l3 = sqrt(pow(p[3].x - p[2].x, 2.0) + pow(p[3].y - p[2].y, 2.0));double l4 = sqrt(pow(p[0].x - p[3].x, 2.0) + pow(p[0].y - p[3].y, 2.0));return l1 + l2 + l3 + l4;}else return 0.0;
}bool Parallelogram::verify(){if(Quadrilateral::verify()){double l1 = sqrt(pow(p[1].x - p[0].x, 2.0) + pow(p[1].y - p[0].y, 2.0));double l2 = sqrt(pow(p[2].x - p[1].x, 2.0) + pow(p[2].y - p[1].y, 2.0));double l3 = sqrt(pow(p[3].x - p[2].x, 2.0) + pow(p[3].y - p[2].y, 2.0));double l4 = sqrt(pow(p[0].x - p[3].x, 2.0) + pow(p[0].y - p[3].y, 2.0));if(fabs(l1 - l3) <= EPS && fabs(l2 - l4) <= EPS) return true;else return false;}else return false;
}
double Parallelogram::getArea(){if(verify()) return Quadrilateral::getArea();else return 0.0;
}
double Parallelogram::getPerimeter(){if(verify()) return Quadrilateral::getPerimeter();else return 0.0;
}bool Rectangle::verify(){if(Parallelogram::verify()){double l1 = sqrt(pow(p[2].x - p[0].x, 2.0) + pow(p[2].y - p[0].y, 2.0));double l2 = sqrt(pow(p[3].x - p[1].x, 2.0) + pow(p[3].y - p[1].y, 2.0));if(fabs(l1 - l2) <= EPS) return true;else return false;}else return false;
}
double Rectangle::getArea(){if(verify()) return Quadrilateral::getArea();else return 0.0;
}
double Rectangle::getPerimeter(){if(verify()) return Quadrilateral::getPerimeter();else return 0.0;
}//填空结束int main()
{vector<Point> vertices;for (int i=0;i<4;i++){double x,y;cin>>x>>y;Point p(x,y);vertices.push_back(p);}Quadrilateral q(vertices);Parallelogram pa(vertices);Rectangle r(vertices);cout<<fixed<<setprecision(2);cout<<(q.verify()?1:0)<<endl;cout<<q.getArea()<<endl;cout<<q.getPerimeter()<<endl;cout<<(pa.verify()?1:0)<<endl;cout<<pa.getArea()<<endl;cout<<pa.getPerimeter()<<endl;cout<<(r.verify()?1:0)<<endl;cout<<r.getArea()<<endl;cout<<r.getPerimeter()<<endl;return 0;
}
当然以上是老师给的原文件填上我的答案之后的,我填的地方有注释标注的,很明显
说实话第一次用继承,虽然上次有用过,但是没那么深入
代码还有可以改进的地方,像在求面积和周长的时候,可以用一个值记录,以及一个值记录是否判断过,避免重复判断