【TOJ 2034】C++实验:面积排序(已知三点,利用二阶行列式求三角形面积)

描述

给定三角形、矩形、圆等二维几何图形,请根据面积从大到小进行排序。

主函数里的代码已经给出,请补充完整,提交时请勿包含已经给出的代码。

int main()
{
	vector<CShape*> vec; //为了使用多态,使用指针数组
	string name;
	int num[3]= {};  //用于存储3种形状的ID
	while(cin>>name)
	{
		if(name=="rectangle")
		{
			CPoint p1, p2;
			cin>>p1>>p2;
			vec.push_back(new CRectangle(name, ++num[0], p1, p2));
		}
		else if(name=="triangle")
		{
			CPoint p1, p2, p3;
			cin>>p1>>p2>>p3;
			vec.push_back(new CTriangle(name, ++num[1], p1, p2, p3));
		}
		else
		{
			CPoint center;
			double r;
			cin>>center>>r;
			vec.push_back(new CCircle(name, ++num[2], center, r));
		}
	}
	sort(vec.begin(), vec.end(), cmp);
	for(int i=0;i<vec.size();i++)
	{
		cout<<vec[i]->GetName()<<" "<<setiosflags(ios::fixed)<<setprecision(3)<<vec[i]->Area()<<endl;
		delete vec[i];
	}

	return 0;
}

输入

输入数据包括有多行,每行为一个几何图形(不超过100个几何图形)。各种几何图形的输入格式如下:

三角形(x1,y1,x2,y2,x3,y3分别为三角形顶点坐标):
triangle x1 y1 x2 y2 x3 y3

矩形(x1,y1,x2,y2为矩形某对角线的端点,矩形的边与坐标轴平行)
rectangle x1 y1 x2 y2

圆(x1,y1为圆心坐标,r为半径)
circle x1 y1 r

输出

对各个图形分别进行编号命名,三角形命名为triangle1、triangle2...,矩形命名为rectangle1、rectangle2...,圆命名为circle1、circle2...

然后按照面积从大到小进行排序,如果面积相同,则根据名字按照字典序排序。每行输出一个形状的名字以及面积,用空格分隔,面积保留3位小数。

样例输入

rectangle 0.0 0.0 1.0 2.0
circle 0.0 0.0 1.0
triangle 0.0 0.0 1.0 1.0 1.0 0.0
rectangle 0.0 0.0 1.0 1.0
circle 0.0 0.0 2.0

样例输出

circle2 12.566
circle1 3.142
rectangle1 2.000
rectangle2 1.000
triangle1 0.500

题解

由于海伦公式的计算会有误差,所以我们利用二阶行列式计算三角形的面积:

设A(x1,y1),B(x2,y2),C(x3,y3)在坐标系中中顺序为三点按逆时针排列S=1/2[(x1y2-x2y1)+(x2y3-x3y2)+(x3y1-x1y3)]ps:最好给面积加个绝对值,有时候会出现负值
#include<bits/stdc++.h>
#define pi acos(-1)
using namespace std;
string ch(string s,int x)
{
    stringstream ss;
    ss<<s<<x;
    ss>>s;
    return s;
}
class CPoint{
public:
    double x,y;
    CPoint(double x=0,double y=0):x(x),y(y){}
    friend istream &operator>>(istream &is,CPoint&p)
    {
        is>>p.x>>p.y;
        return is;
    }
};
class CShape{
public:
    double m;
    string name;
    CShape(string name,double m):m(m),name(name){}
    double Area(){return m;}
    string GetName(){return name;}
};
int cmp(CShape *a,CShape *b)
{
    if(a->m>b->m)return 1;
    if(a->m==b->m)
    {
        if(a->name<b->name)
            return 1;
        else return 0;
    }
    return 0;
}

class CTriangle:public CShape{
private:
    CPoint p1, p2, p3;
    int num;
public:
    CTriangle(string name,int num,CPoint p1,CPoint p2,CPoint p3)
    :p1(p1),p2(p2),p3(p3),CShape(ch(name,num),fabs(0.5*((p1.x*p2.y-p2.x*p1.y)+(p2.x*p3.y-p3.x*p2.y)+(p3.x*p1.y-p1.x*p3.y)))),num(++num){}
};

class CRectangle:public CShape{
private:
    CPoint p1, p2;
public:
    int num;
    CRectangle(string name,int num,CPoint p1,CPoint p2)
    :CShape(ch(name,num),fabs((p1.x-p2.x)*(p1.y-p2.y))),num(++num),p1(p1),p2(p2){}
};

class CCircle:public CShape{
private:
    CPoint p;
    int num;
    double r;
public:
    CCircle(string name,int num,CPoint p,double r)
    :CShape(ch(name,num),pi*r*r),num(++num),p(p),r(r){}
};
int main()
{
    vector<CShape*> vec; //为了使用多态,使用指针数组
    string name;
    int num[3]= {};  //用于存储3种形状的ID
    while(cin>>name)
    {
        if(name=="rectangle")
        {
            CPoint p1, p2;
            cin>>p1>>p2;
            vec.push_back(new CRectangle(name, ++num[0], p1, p2));
        }
        else if(name=="triangle")
        {
            CPoint p1, p2, p3;
            cin>>p1>>p2>>p3;
            vec.push_back(new CTriangle(name, ++num[1], p1, p2, p3));
        }
        else
        {
            CPoint center;
            double r;
            cin>>center>>r;
            vec.push_back(new CCircle(name, ++num[2], center, r));
        }
    }
    sort(vec.begin(), vec.end(), cmp);
    for(int i=0;i<vec.size();i++)
    {
        cout<<vec[i]->GetName()<<" "<<setiosflags(ios::fixed)<<setprecision(3)<<vec[i]->Area()<<endl;
        delete vec[i];
    }

    return 0;
}

原文地址:https://www.cnblogs.com/kannyi/p/9057486.html

时间: 2024-07-31 21:29:38

【TOJ 2034】C++实验:面积排序(已知三点,利用二阶行列式求三角形面积)的相关文章

Scala实现:已知三点坐标,求最短距离(如果在垂足不在线段内,最短距离为到其中一点的直线距离)

/** * 已知三点坐标,求其中一点到另两点的垂线距离 * (如果在垂足不在线段内,最短距离为到其中一点的直线距离) * Created by wzq on 17-11-2. */object Point2lineDistance { def main(args: Array[String]) { val v: Double = pointToLine(-3, 0, 3, 0, 0, 3) System.out.println(v) } def pointToLine(x1: Int, y1:

编程题:指针变量,实参与形参的引用。已知一个一维数组,求其中前n个数的和。n由键盘输入。

#include<stdio.h> int sum(int *q,int n) { int i,s=0; for(i=0;i<n;i++,q++) s+=*q; return s; } void main() { int num,a[10]={1,2,3,4,5,6,7,8,9,10}; int *p=a; scanf("%d",&num); printf("%d\n",sum(p,num)); } 编程题:指针变量,实参与形参的引用.已知

编程题:已知一个一维数组,求其中前n个数的和。n由键盘输入

#include<stdio.h> int sum(int array[],int n) { int i,s=0; for(i=0;i<n;i++) s+=array[i]; return s; } void main() { int num,a[10]={1,2,3,4,5,6,7,8,9,10}; scanf("%d",&num); printf("%d\n",sum(a,num)); } 编程题:已知一个一维数组,求其中前n个数的和.

59.已知xxz+yzz=532,求所有可能的x,y,z的值

#include<iostream> using namespace std; int main() { for(int x=0;x<10;x++) { for(int y=0;y<10;y++) { for(int z=0;z<10;z++) { if((110*x+100*y+12*z)==532) { cout<<"x="<<x<<" "; cout<<"y="&

已知IP、子网掩码,求网络位、主机位、广播地址

前       言 本文档是简单介了逻辑算法.以及如何在已知IP地址和子网掩码的情况下计算网络位.主机位以及广播地址.所有步骤远的采用最原始的二进制方式,直击原理,请仔细阅读. 1.逻辑算法 在计算网络位.主机地址.广播地址时,会使用到逻辑与运算和逻辑或运算,所以了解其算法是必要的.详细章节请百度,这里只做简单介绍. &&是逻辑与运算符,|| 是逻辑或运算符 逻辑与运算:当两个二进制数1和0做逻辑与运算时,全为真(1)即结果为真(1),一个为假即全为假(0) 逻辑或运算:当两个二进制数1和

已知三点求圆心与半径

已知三点求圆心与半径  [email protected] http://blog.csdn.net/kezunhai 在计算机图像图形学中,经常会用到求圆心或圆半径的情况,本文介绍一种已知三个点求圆心和圆半径的方法(当然三个点不能共线,共线的三个点不能构成圆). 原理:相互连接三个点,选取其中的任意两条直线,通过对这两条直线的中心做垂线,两条垂线的交点就是圆心,以此点为圆心,以此点到任意一点的距离为半径画圆. 三个点分别计为pt1, pt2, pt3:取直线p1p2和p1p3(也可以取其他直线

数据结构——已知先序中序求后序,已知中序后序求先序

总结下二叉树的已知两种遍历方式求第三种遍历顺序的方法,已知先序和中序遍历或者后序与中序遍历后二叉树是唯一确定的,下面介绍怎么求出第三种遍历顺序. 先序遍历顺序为:根结点——左子结点——右子结点,中序遍历为:左子结点——根结点——右子结点,我们注意到,先序遍历的第一个元素就是二叉树根结点,我们在中序遍历中以该元素分为左右两部分,则左边为左子树,右边为右子树,递归即可还原二叉树,这个过程中可直接输出后序遍历的顺序.同理,可以用后序与中序还原出先序遍历的顺序. 代码及测试数据如下: 1 #includ

OJ期末刷题 问题 B: 求三角形面积-gyy

题目描述 输入三条边的长度,如果这三条边能构成三角形,则需要计算三角形面积,如果不能构成三角形则输出提示信息 "error input".输出的面积按两位小数方式输出 输入 三条边的长度 输出 如果这三条边能构成三角形,则输出该三角形面积,如果这三条边不能构成三角形,则输出提示信息"error  input" 样例输入 3.3 4.4 5.5 样例输出 area=7.26 提示 输出面积时保留两位小数 代码: #include <iostream> #i

【c语言】给出三角形的三边长,求三角形面积

// 给出三角形的三边长,求三角形面积 // area = sqrt( s * ( s - a ) * ( s - b ) * ( s - c ) ) // s = ( a + b + c) / 2 #include <stdio.h> #include <math.h> int main() { int a,b,c; double s,area; printf("请输入三角形三个边长:"); scanf("%d%d%d",&a,&a