oj实验8

题1:
InputOutput
描述
设计一个保存你个人信息的类,包含姓名和年龄。并使用以下代码测试


int main()
{
    string    name;
    int    year;
    cin >> name >> year;
    PersonInfo info(name, year);
    cout << "I am " << info.Name() << ", " << info.Age() << " years old.\n";
    return 0;
}

在这里插入图片描述

#include<iostream>
#include<string>
using namespace std;
class PersonInfo
{
public:
    PersonInfo(string m_name, int m_year){name=m_name;year=m_year;}
 string Name(){return name;}
 int Age(){return year;}
  
private:
 string name;
 int  year;
};

题2:
Composite

描述
计算机包含CPU和硬盘。请设计Computer、CPU、Disk类。并满足以下测试

int main()
{
    string cpuType, diskType;
    double frequency, capacity;
    cin >> cpuType >> frequency >> diskType >> capacity;
    CPU cpu(cpuType, frequency);
    Disk disk(diskType, capacity);
    Computer computer(cpu, disk);

    computer.Print();
    return 0;
}

输入
cpu类型 cpu主频 disk类型 disk容量
在这里插入图片描述

#include<iostream>
#include<string>
using namespace std;

class CPU
{
public:
    CPU() {} //有非默认的对象初始化函数,则需要写无参构造函数
    CPU(string _type, double _frenquency) :cpuType(_type), frenquency(_frenquency) {}
    string gettype(void) { return this->cpuType; }
    double getfreq(void) { return this->frenquency; }
private:
    string cpuType;
    double frenquency;
  
};

class Disk
{
  public:
    Disk() {}
    Disk(string _type, double _capacity) :diskType(_type), capacity(_capacity) {}
    string gettype(void) { return this->diskType; }
    double getcapacity(void) { return this->capacity; }
private:
    string diskType;
    double capacity;
  
};

class Computer
{
public:
    Computer() {}
    Computer(CPU _cpu, Disk _disk) :C_CPU(_cpu), C_Disk(_disk) {}
    void Print()
    {
        cout << "The computer has a cpu and a disk." << endl;
        cout << "CPU type: " << C_CPU.gettype() << ", CPU frequency: " << C_CPU.getfreq() << " GHz" << endl;
        cout << "disk type: " << C_Disk.gettype() << ", disk capacity: " << C_Disk.getcapacity() << " T" << endl;
        //此处直接用类的对象调用的函数,并直接在输出里使用的,原函数的作用是返回值(见上,对这两个函数的构造)
    }
private:
    CPU C_CPU;
    Disk C_Disk;
};

题三:
静态数据成员

描述
定义一个学生类Student如下:

class Student
{
private:
    int age;   //年龄
    string name;  //姓名
public:
    static int count; //静态成员,表示学生人数
    Student(int a, string n);
    Student();
    ~Student();
    void Print();
};

主函数的定义及程序的运行结果如下,请完成类的定义及类中各函数的实现代码,补充成一个完整的程序。

int main()
{
    cout<<"count="<<Student::count<<endl;
    Student s1, *p=new Student(23,"ZhangHong");
    s1.Print();
    p->Print();
    delete p;
    s1.Print();
    Student Stu[4];
    cout<<"count="<<Student::count<<endl;
    return 0;
}

在这里插入图片描述

#include<iostream>
#include<string>
using namespace std;

int Student::count=0;
 Student::Student(int a, string n)
    {
       age=a;
       name=n;
       count=5;
    };
    
 Student::Student(){age=0;name="NoName";}
 Student::~Student(){}
 void  Student::Print()
    {
        cout<<"Name="<<name<<", "<<"age="<<age<<endl;
    }

题4:
Ellipse

描述
已有一个点类Point,使用x和y两个参数确定:

class Point
{
private:
    double x, y;
public:
    Point(double a=0, double b=0):x(a),y(b) {}
    ~Point(){}
    double getX() const { return x;}
    double getY() const { return y;}
    void setX(double a) { x = a; }
    void setY(double b) { y = b; }
};

假定椭圆中心固定于原点 (0,0),则唯一由半长轴 x 和半短轴 y 确定,故可使用一个点对象作为椭圆类成员。由点类组合方式生成一个椭圆类

class Ellipse
{
public:
    Point pAxis;
    Ellipse(double x = 0, double y = 0):pAxis(x,y) { }//这里在椭圆类里使用了点类的对象
    ~Ellipse() { }
    Ellipse(const Ellipse&);
    Ellipse transposition();    // 转置(交换长短半轴)
    double area();            // 面积
    double eccentricity();        // 离心率
    string position(const Point);    // 位置关系
};

测试多组数据,输入椭圆分别在x轴、y轴的截距的绝对值(半轴长)和点的坐标,要求:输出椭圆面积、椭圆离心率、点与椭圆的位置关系。

(点在椭圆内、上、外<==>输出“inside”“at”“outside”)

主函数提供如下:

int main()
{
    double a,b;
    while(cin>>a>>b)
    {
        Ellipse d1(a,b),d2(d1),d3=d2.transposition();
        cout<<d1.area()<<endl;
        cout<<d2.eccentricity()<<endl;
        cin>>a>>b;
        Point p(a,b);
        cout<<d3.position(p)<<endl;
    }
    return 0;
}

注意:const double PI = acos(-1.0);声明为全局变量

在这里插入图片描述

Ellipse::Ellipse(const Ellipse&t)
{
    this->pAxis=t.pAxis;
}//第一遍做时在这出错

Ellipse Ellipse::transposition()
{
    double tempt1,tempt2;
    tempt1=this->pAxis.getY();
    tempt2 = this->pAxis.getX();
    this->pAxis.setY(tempt2);
    this->pAxis.setX(tempt1);
    return *this;
}// 转置(交换长短半轴)这一段代码着重关注,学会用this!
double Ellipse::area()
{
    return (PI*(pAxis.getX())*(pAxis.getY()));
}// 面积
double Ellipse::eccentricity()
{
    if(pAxis.getX()>pAxis.getY())
        return (sqrt(pAxis.getX()*pAxis.getX()-pAxis.getY()*pAxis.getY())/pAxis.getX());
    else return (sqrt(pAxis.getY()*pAxis.getY()-pAxis.getX()*pAxis.getX())/pAxis.getY());
    
}// 离心率(注意分类讨论!)
string Ellipse::position(const Point p)
{
    if((pow(p.getX(),2)/pow(this->pAxis.getX(),2))+(pow(p.getY(),2)/pow(this->pAxis.getY(),2))==1)
        return "at";
    if((pow(p.getX(),2)/pow(this->pAxis.getX(),2))+(pow(p.getY(),2)/pow(this->pAxis.getY(),2))>1)
        return "outside";
        else return "inside";
}

题五:
AdvancedInheritance

描述
不同的动物既有共性也有个性。鸟类会飞,鱼会游泳。请设计类的层次结构进行表示,并通过以下测试

int main()
{
    Animal *animal;
    string type, color;
    bool Osteichthyes, daytime;
    cin >> type >> color >> Osteichthyes;
    Fish fish(type, color, Osteichthyes);
    fish.Print();  //输出方式一
    animal = &fish;
    animal->Print();//输出方式二
    cin >> type >> color >> daytime;
    Bird bird(type, color, daytime);
    bird.Print();//输出方式一
    animal = &bird;
    animal->Print();//输出方式二
    return 0;
}

输入
鱼类型 鱼的颜色 是否硬骨鸟类型 鸟的颜色 是否白天活动
输出
见样例,冒号和逗号后有一个空格
在这里插入图片描述

//!!!这道题的要点在于,如何让Fish和Bird两个类的对象,调用具有相同名字的Print函数时,能够区分开二者,这就需要使用到 **类的层次结构** 的知识
#include<iostream>
#include<string>
using namespace std;
class Animal
{
public:
    string type, color;
    virtual void Print(){}  //类的层次结构
};

class Fish: public Animal
{
public:
    Fish(const string m_type,const string m_color,bool m_Osteichthyes)
    {
        type=m_type;
        color=m_color;
        Osteichthyes=m_Osteichthyes;
    }
    virtual void Print()  // 类的层次结构
    {  cout<<"type: "<<type<<", color: "<<color<<", Osteichthyes: "<< Osteichthyes <<endl;}
private:
    bool Osteichthyes;
};

class Bird: public Animal
{
public:
    Bird(const string m_type,const string m_color,bool m_daytime)
    {
        type=m_type;
        color=m_color;
        daytime=m_daytime;
    }
    virtual void Print()  //类的层次结构
       {  cout<<"type: "<<type<<", color: "<<color<<", daytime: "<<daytime<<endl;}
private:
    bool daytime;
};

题六(points!):
有理数类

描述
设计一个有理数类Rational,要求对运算符“+”“-”“*”“/”和“+=”“-=”“=”“/=”进行重载,完成有理数的加减乘除以及加减乘除复合赋值运算;并且重载“<<”和“>>”操作符完成有理数的输入和输出。最后,重载“==”和“!=”比较两个有理数是否相等。

类的定义如下:

class Rational
{
private:
    int z;    //分子
    int m;    //分母

public:
    Rational(int a=0, int b=1);  //构造有理数分数,分子默认为0,分母默认为1
    void yuefen(); //约分函数对分数化简
    friend Rational operator+(const Rational &r1, const Rational &r2);
    friend Rational operator-(const Rational &r1, const Rational &r2);
    friend Rational operator*(const Rational &r1, const Rational &r2);
    friend Rational operator/(const Rational &r1, const Rational &r2);
    Rational & operator+=(const Rational &r);
    Rational & operator-=(const Rational &r);
    Rational & operator*=(const Rational &r);
    Rational & operator/=(const Rational &r);
    friend bool operator==(const Rational &, const Rational &);//判断两个有理数是否相等
    friend bool operator!=(const Rational &, const Rational &);//判断两个有理数是否不等
    friend ostream & operator<<(ostream &, const Rational &);
    friend istream & operator>>(istream &, Rational &);
};

使用以下的main函数体进行测试:

int main()
{
    Rational r1, r2, r3;

    while (cin >> r1 >> r2)
    {
        cout << "r1 = " << r1 << "\n" << "r2 = " << r2 << endl;
        r3 = r1 + r2;
        cout << "r1+r2 = " << r3 << endl;
        r3 = r1 - r2;
        cout << "r1-r2 = " << r3 << endl;
        r3 = r1 * r2;
        cout << "r1*r2 = " << r3 << endl;
        r3 = r1 / r2;

        cout << "r1/r2 = " << r3 << endl;
        cout << (r1 == r2) << " " << (r1 != r2) << endl;
        cout << (r1 += r2) << endl;
        cout << (r1 -= r2) << endl;
        cout << (r1 *= r2) << endl;
        cout << (r1 /= r2) << endl;
    }

    return 0;
}

注意

  • ***Rational& yuefen();该函数原理是求得分子和分母的最大公约数gcd,然后将m和z除以gcd得到最简分数形式。求最大公约数的方法叫做辗转相除法,具体可上网查询。

  • 观察输出,负号总是在分子前,若输入不符合该情形,需做相应处理。

  • 分数总以化简形式输出,可在所有成员函数及运算符函数内恰当位置调用yuefen函数予以保证***

在这里插入图片描述

int gcd(int a, int b)
 {
   int temp;
   temp = a = abs(a);
   b = abs(b);
   a = a < b ? b : a;
   b = temp < b ? temp : b;
   if(a%b!=0)
         return gcd(a%b,b);
   else
         return b;
 }
Rational::Rational(int a, int b)
{
    z=a;
    m=b;
}

 Rational operator+(const Rational &r1, const Rational &r2)
{
    
    Rational r;
    r.z=r1.z*r2.m+r2.z*r1.m;
    r.m=r1.m*r2.m;
    r.yuefen();
    return r;
}
Rational operator*(const Rational &r1, const Rational &r2)
   {
      
       Rational r;
       r.z=r1.z*r2.z;
       r.m=r1.m*r2.m;
       r.yuefen();
       return r;
   }

Rational operator-(const Rational &r1, const Rational &r2)
{
    Rational r;
    r.z=r1.z*r2.m-r2.z*r1.m;
    r.m=r1.m*r2.m;
    r.yuefen();
    return r;
}
 Rational operator/(const Rational &r1, const Rational &r2)
{
    
    Rational r;
    r.z=r1.z*r2.m;
    r.m=r1.m*r2.z;
    r.yuefen();   //注意yuefen()函数的不同调用方式
    return r;
}
 Rational& Rational::operator+=(const Rational &r)
{
    int a=this->z,b=this->m;
    this->z=a*r.m+r.z*b;
    this->m=b*r.m;
    yuefen();   //注意yuefen()函数的不同调用方式
    return *this;
}
Rational & Rational::operator/=(const Rational &r)
   {
       int a=this->z,b=this->m;
       this->z=a*r.m;
       this->m=b*r.z;
       yuefen();
       return *this;
   }

Rational & Rational::operator-=(const Rational &r)
{
    int a=this->z,b=this->m;
    this->z=a*r.m-r.z*b;
    this->m=b*r.m;
    yuefen();
    return *this;
}

Rational & Rational::operator*=(const Rational &r)
{
    int a=this->z,b=this->m;
    this->z=a*r.z;
    this->m=b*r.m;
    yuefen();
    return *this;
}

bool operator!=(const Rational &r1, const Rational &r2)//判断两个有理数是否不等
   {
       int t;
       int r1m=0,r1z=0,r2m,r2z;
       t = gcd(r1.z, r1.m);
       r1z= r1z / t;
       r1m = r1m / t;
       t = gcd(r2.z, r2.m);
       r2z = r2.z / t;
       r2m = r2.m / t;
       if  (r1m == r2m&&r1z == r2z)
           return false;
       else
           return true;
   }

bool operator==(const Rational &r1, const Rational &r2)//判断两个有理数是否相等
{
    int t;
    int r1m=0,r1z=0,r2m,r2z;
    t = gcd(r1.z, r1.m);
    r1z= r1z / t;
    r1m = r1m / t;
    t = gcd(r2.z, r2.m);
    r2z = r2.z / t;
    r2m = r2.m / t;
    if (r1m == r2m&&r1z == r2z)
        return true;
    else
        return false;
}

ostream & operator<<(ostream &os, const Rational &r)
{
    
    os<<r.z<<"/"<<r.m;
    return os;
}
istream & operator>>(istream &is, Rational &r)
{
    is>>r.z>>r.m;
    r.yuefen();
    return is;
}


void Rational::yuefen()
{
   
    int x=abs(z),y=abs(m),t; //abs(),求绝对值函数
    t=gcd(x,y);
    z/=t;m/=t;
    if(m<0)
    {
        z=-z;
        m=-m;
    }//控制负号一直在前面
}

题七:
Line

描述
表示点和线是几何学的基础。请实现模板类的点(Point2)以及线段(Line2),并计算线段长度 Line2::Length();完成以上类,并通过以下测试

int main() 
{
    Point2<double> pt1(1.0, 1.0);
    Point2<double> pt2(3.0, 4.0);
    Line2<double> line(pt1, pt2);
    cout << line.Length() << endl;

    int x1,y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    Line2<int> nLine(Point2<int>(x1, y1), Point2<int>(x2, y2));
    cout << nLine.Length()<< endl;

    return 0;
}

在这里插入图片描述

#include<iostream>
#include<cmath>
using namespace std;
template<class type>
class Point2
{
public:
    Point2(type a,type b)
    {
        x=a;
        y=b;
    }
    type x;
    type y;
};


template<class type>
class Line2
{
public:
    Line2(Point2<type> m_p1,Point2<type> m_p2):p1(m_p1),p2(m_p2){}
  type Length()
    {
        return (sqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2)));
    }
private:
    Point2<type> p1,p2;
    type l1,l2;
};

题八:
铁轨

描述
某城市有一个火车站,铁轨铺设如图所示。有n节车厢从A方向驶入车站,按进站顺序编号为1~n。你的任务是让它们按照某种特定的顺序进入B方向的铁轨并驶出车站。为了重组车厢,你可以借助中转站C。这是一个可以停放任意多节车厢的车站,但由于末端封闭,驶入C的车厢必须按照相反的顺序驶出C。对于每个车厢,一旦从A移入C,就不能再回到A了;一旦从C移入B,就不能回到C了。换句话说,在任一时刻,只有两种选择:A->C和C->B。
请编程判断:按给定的出站顺序,火车能否出站。

在这里插入图片描述

在这里插入图片描述

#include<iostream>
#include <stack>
using namespace std;
const int maxn=1005;
int n,rail[maxn];
int main()
{
    while(scanf("%d",&n)==1)
    {
        stack<int > s;
        for(int i=1;i<=n;i++)
        {
            cin>>rail[i];
        }
        int flag,a,b;
        a=b=flag=1;
        while(b<=n)
        {
            if(a==rail[b])
            {
                a++;
                b++;
            }
            else if(!s.empty()&&s.top()==rail[b])
            {
                s.pop();
                b++;
            }
            else if(a<=n)
                s.push(a++);
            else
            {
                flag=0;
                break;
            }
        }
        printf("%s\n",flag?"Yes":"No");
    }
    return 0;
}
  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值