面向对象程序设计-09-期中模拟

声明

题解包含以下内容:

  • (相对)高级的 C++ 模板及语法技巧
  • 仅适用于 C++20 标准的代码
  • 强烈的个人代码风格和 Modern C++ 范式追求
  • 泛滥的标准库函数

换句话说就是(相较于其他公开题解)更低的查重率和更高的使用门槛;请酌情使用。

【id:119】【25分】A. 机器人变身(类与对象)

题目描述

编写一个机器人类,包含属性有机器名、血量、伤害值、防御值、类型和等级。其中血量、伤害和防御和等级、类型相关:
普通型机器人,类型为N,血量、伤害、防御是等级的5倍
攻击型机器人,类型为A,攻击是等级的10倍,其他属性和普通的一样
防御型机器人,类型为D,防御是等级的10倍,其他属性和普通的一样
生命型机器人,类型为H,生命是等级的50倍,其他属性和普通的一样。

机器人操作包括:打印、各个属性的获取和设置方法,构造函数可有可无,根据需要自行编写,

编写一个全局函数用于机器人变身,使得各种类型机器人能够相互转变。参数包括机器人对象指针和变身后的机器人类型,功能是修改机器人类型,并更改相关的属性。如果变身类型和机器人原来的类型不同,则执行变身功能,并返回true;如果变身类型和原来类型相同,则不执行变身,并返回false.

要求所有数据成员都是私有属性,用C++语言和面向对象设计思想来编程实现上述要求

输入

第一行输入t,表示要执行t次机器人变身

接着每两行,一行输入一个机器人的属性,包括机器名、类型、等级,机器名最大长度为20,另一行输入变身类型

依次类推输入

输出

每行输出变身后的机器人信息,要求调用机器人的打印方法来输出,即使机器人不变身也输出

属性输出依次为:名称、类型、等级、血量、伤害、防御

最后一行输出执行变身的次数

样例

输入样例1输出样例1
3
X001 N 5
H
X002 A 5
D
X003 D 5
D
X001–H–5–250–25–25
X002–D–5–25–25–50
X003–D–5–25–25–50
The number of robot transform is 2

Answer

#include <bits/stdc++.h>
using namespace std;

class Robot {
  char type;
  int level;
  string name;

  int health;
  int damage;
  int defence;

  void update_attr() noexcept {
    health = 5 * level;
    damage = 5 * level;
    defence = 5 * level;

    if ( type == 'A' )
      damage = 10 * level;
    else if ( type == 'D' )
      defence = 10 * level;
    else if ( type == 'H' )
      health = 50 * level;
  }

public:
  Robot( char tp, int lv, string nm )
    : type { tp }, level { lv }, name { move( nm ) } {
    update_attr();
  }
  Robot() : Robot( 'N', 0, "" ) {}
  auto getType() const { return type; }
  auto getLevel() const { return level; }
  auto getName() const { return name; }
  auto getHealth() const { return health; }
  auto getDamage() const { return damage; }
  auto getDefence() const { return defence; }
  void print() {
    cout << name << "--"
      << type << "--"
      << level << "--"
      << health << "--"
      << damage << "--"
      << defence << endl;
  }
  friend bool transformer( Robot* rbt, char tp ) {
    if ( rbt->type == tp )
      return false;

    rbt->type = tp;
    rbt->update_attr();

    return true;
  }
  friend istream& operator>>( istream& is, Robot& rbt ) {
    is >> rbt.name >> rbt.type >> rbt.level;
    rbt.update_attr();
    return is;
  }
};

int main()
{
  int t; cin >> t;
  Robot rbt;
  int cnt = 0;
  while ( cin >> rbt ) {
    char tp {}; cin >> tp;
    if ( transformer( &rbt, tp ) )
      ++cnt;
    rbt.print();
  }
  cout << "The number of robot transform is " << cnt << endl;
}

【id:120】【25分】B. 虚拟电话(构造与析构)

题目描述

虚拟电话包含属性:电话号、状态、机主姓名。
1、电话号是一个类,它包含号码和类型,其中号码是整数类型,类型用单个字母表示用户类别,A表示政府,B表示企业、C表示个人。类操作包括构造、属性的获取和设置等方法,根据需要自行编写。
2、状态用一个数字表示,1表示在用,0表示未用,
3、机主姓名是一个字符串

电话操作包括:构造、析构、打印和查询。
1、构造函数需要考虑复合类成员的构造,并且输出提示信息。假设电话号码为12345678,则构造函数输出"12345678 constructed."
2、打印是输出电话的相关信息,其中如果电话状态是在用则输出use;状态是未用则输出unuse,输出格式看示例。
3、析构函数是输出提示信息。假设电话号为12345678,则析构函数输出"12345678 destructed. "
4、查询操作是根据给定的号码查询电话,如果电话自身号码和给定号码不相同,则返回0;如果电话自身号码和给定号码相同,则返回1

用C++和面向对象思想实现以下要求:
1、输入相关数据,创建三个电话对象,并通过构造方法初始化。
2、输入若干个电话号码,通过查询操作查询这些号码是否在三个电话对象中,如果不存在输出"wrong number.",存在则调用打印操作输出电话信息,具体看输出样例。

输入

头三行输入三个电话信息,每行包括电话号码、电话类型、状态、机主姓名,机主姓名最大长度为20

接着一行输入t,表示有t个号码要查询

接着t行输入t个电话号码

输出

t行输出t个号码的查询结果

样例

输入样例1输出样例1
80000001 A 1 tom
80000002 B 0 ken
80000003 C 1 mary
3
50000002
80000003
80000002
80000001 constructed.
80000002 constructed.
80000003 constructed.
wrong number.
Phone=80000003–Type=C–State=use–Owner=mary
Phone=80000002–Type=B–State=unuse–Owner=ken
80000003 destructed.
80000002 destructed.
80000001 destructed.

Answer

#include <bits/stdc++.h>
using namespace std;

class PhoneNumber {
  uint64_t phone_num;
  char type;

public:
  explicit PhoneNumber( uint64_t ph_n = 0, char tp = '\0' )
    : phone_num { ph_n }, type { tp } {
  }
  auto getPhone() const { return phone_num; }
  bool operator==( uint64_t ph_num ) const {
    return phone_num == ph_num;
  }
  friend ostream& operator<<( ostream& os, const PhoneNumber& ph ) {
    return os << "Phone=" << ph.phone_num << "--Type=" << ph.type;
  }
};

class VirtualPhone {
  PhoneNumber ph;
  bool status;
  string name;

public:
  VirtualPhone( PhoneNumber ph, bool _status, string nm )
    : ph { move( ph ) }, status { _status }, name { move( nm ) } {
    cout << ph.getPhone() << " constructed.\n";
  }
  VirtualPhone( VirtualPhone&& rhs ) {
    ph = move( rhs.ph );
    status = rhs.status;
    name = move( rhs.name );
  }
  ~VirtualPhone() {
    cout << ph.getPhone() << " destructed.\n";
  }
  bool query( uint64_t ph_num ) const {
    return ph == ph_num;
  }
  friend ostream& operator<<( ostream& os, const VirtualPhone& vp ) {
    return os << vp.ph << "--State="
      << (vp.status ? "use"sv : "unuse"sv) << "--Owner="
      << vp.name;
  }
};

int main()
{
  list<VirtualPhone> arr;
  for ( size_t i = 0; i < 3; ++i ) {
    size_t ph_num {}; char tp {};
    int st {}; string nm {};
    cin >> ph_num >> tp >> st >> nm;
    arr.emplace_back( PhoneNumber( ph_num, tp ), st, move( nm ) );
  }
  size_t t {}; cin >> t;
  while ( t-- ) {
    uint64_t ph_num {}; cin >> ph_num;
    if ( auto iter = find_if( arr.begin(), arr.end(),
          [ph_num]( auto&& e ) -> bool { return e.query( ph_num ); } );
         iter != arr.end() )
      cout << *iter << endl;
    else cout << "wrong number.\n";
  }
  while ( !arr.empty() ) // 维持析构顺序
    arr.erase( prev( arr.end() ) );
}

【id:121】【25分】C. 银行账户(拷贝构造)

题目描述

银行账户包括余额、利率、号码、类型等属性,其中号是固定8位整数,类型表示个人还是企业账户,如果是个人用P标识,企业用E标识。

账户又分为活期账户和定期账户,活期利率为0.5%,定期利率为1.5%。

账户操作有计息、查询操作。计息操作是根据利率计算利息,并把利息增加到余额中,并做相关信息输出。查询操作是输出账户的全部信息。

创建一个活期账户,并通过构造函数初始化各个属性。然后通过拷贝构造来创建一个定期账户,信息与活期账户基本相同,不同之处包括:定期账户号码是活期账户号码加50000000(7个0);利率是定期利率。

要求所有数据成员都是私有属性

用C++语言的类与对象思想来编写程序实现上述要求

输入

输入测试个数t,表示有t个活期账户

先输入一个活期账户的账户号码、账户类型、余额(根据输入创建活期账户和定期账户)

接着输入两个操作符,第一个操作符对活期账户操作,第二个操作符对定期账户进行操作。若输入大写字母C表示计息操作,若输入大写字母P表示查询操作

以此类推输入其他账户的信息和操作

输出

每两行输出一对活期账户和定期账户的操作结果。

样例

输入样例1输出样例1
2
12345678 P 10000
C P
23456789 E 20000
P C
Account=12345678–sum=10050
Account=62345678–Person–sum=10000–rate=0.015
Account=23456789–Enterprise–sum=20000–rate=0.005
Account=73456789–sum=20300

Answer

#include <bits/stdc++.h>
using namespace std;

class BankAccount {
  double balance;
  int num;
  char type;
  double interest_rate;

public:
  BankAccount( double balan, int id, char tp )
    : balance { balan }, num { id }, type { tp } {
    interest_rate = 0.005;
  }
  BankAccount() : BankAccount( 0, 0, '\0' ) {}
  void change_to_fixed() {
    num += 50000000;
    interest_rate = 0.015;
  }
  void interest_accrual() {
    balance += balance * interest_rate;
    cout << "Account=" << num << "--sum=" << fixed << setprecision(0) << balance << endl;
  }
  void query() {
    cout << "Account=" << num << "--" <<
      (type == 'P' ? "Person" : "Enterprise") <<
      "--sum=" << fixed << setprecision(0) << balance <<
      "--rate=" << fixed << setprecision(3) << interest_rate << endl;
  }
  friend istream& operator>>( istream& is, BankAccount& lhs ) {
    return is >> lhs.num >> lhs.type >> lhs.balance;
  }
};

int main()
{
  size_t t {}; cin >> t;
  while ( t-- ) {
    BankAccount current_acc;
    cin >> current_acc;
    BankAccount fixed_account = current_acc;
    fixed_account.change_to_fixed();
    char op1 {}, op2 {};
    cin >> op1 >> op2;
    if ( op1 == 'C' )
      current_acc.interest_accrual();
    else current_acc.query();
    if ( op2 == 'C' )
      fixed_account.interest_accrual();
    else fixed_account.query();
  }
}

【id:122】【25分】D. 电视遥控(静态+友元)【期中模拟】

题目描述

电视机包含音量、模式、频道号等属性,其中模式分为TVDVD两种。电视机在TV模式下,将播放相应频道的内容;在DVD模式下,电视机使用统一的频道号播放DVD的内容,频道号统一为99。另外,电视机采用静态成员的方法共享两个数据:播放电视的电视机数量和播放DVD的电视机数量,初始都为0。

电视机操作包括打印、相关静态函数、属性的获取和设置等,根据需要自行编写。

现编写一个遥控器函数,通过友元方法对电视机进行控制,它的参数包括电视机对象、模式、变化音量、频道号,无返回值。函数操作包括:
1、对电视机对象进行模式设置,如果设置为DVD模式,则频道号参数一定是99;如果设置TV模式,则要把频道号设置相应的值。
2、根据变化音量进行调整,例如原有音量为50,现输入变化音量为-30,则50-30=20,音量最终为20。音量值最低为0,最高为100,超过范围则音量不再变化。
3、更新当前播放电视和播放DVD的电视机数量
4、调用电视机对象的打印方法输出电视相关信息
提示:如果电视机原来模式和参数传递的模式是相同的,那么实际操作就是调整音量、切换频道和输出信息。
注意:函数第一个参数必须是一个电视机对象,不可以是整数类型,可以是对象、或对象指针、或对象引用,根据需要自行编写。

用动态数组方法创建n台电视机,从1开始编号,频道号为编号,音量初始为50,模式为TV,然后通过遥控器函数对电视机进行控制。

所有类的数据成员都是私有属性。请使用C++语言和面向对象思想来实现上述要求

输入

第一行输入n,表示有n台电视台

第二行输入t,表示将执行t次遥控操作

接着输入t行,每行依次输入电视机编号i、模式k、频道号x和变化音量,其中i表示第i台电视机,k为1表示TV模式,k为2表示DVD模式。

输出

每行输出执行遥控操作后的电视机信息

最后一行输出当前播放电视和播放DVD的电视机数量。

具体格式看样例

样例

输入样例1输出样例1
10
5
3 1 11 20
4 2 99 -20
5 2 99 80
5 1 55 -60
6 2 99 -70
第3号电视机–TV模式–频道11–音量70
第4号电视机–DVD模式–频道99–音量30
第5号电视机–DVD模式–频道99–音量100
第5号电视机–TV模式–频道55–音量40
第6号电视机–DVD模式–频道99–音量0
播放电视的电视机数量为8
播放DVD的电视机数量为2

Answer

#include <bits/stdc++.h>
using namespace std;
#define TV 1
#define DVD 2

class Television {
  static int tv_num;
  static int dvd_num;

  int mode;
  int volume;
  int channel_id;
  int id;

public:
  static int num_dvd() { return dvd_num; }
  static int num_tv() { return tv_num; }

  Television( int md = TV )
    : mode { md }, volume { 50 } {
    channel_id = id = dvd_num + tv_num + 1;
    mode == DVD ? ++dvd_num : ++tv_num;
  }
  ~Television() {
    mode == DVD ? --dvd_num : --tv_num;
  }
  Television& adjust_vol( int variation ) {
    auto tmp = volume + variation;
    volume = tmp > 100 ? 100 : tmp < 0 ? 0 : tmp;
    return *this;
  }
  Television& set_mode( int md, int channel = 0 ) {
    if ( md == DVD ) {
      channel_id = 99;
      if ( mode != DVD ) {
        ++dvd_num;
        --tv_num;
      }
    }
    else {
      channel_id = channel;
      if ( mode != TV ) {
        --dvd_num;
        ++tv_num;
      }
    }
      mode = md;
    return *this;
  }
  friend ostream& operator<<( ostream& os, const Television& tv ) {
    return os << "第" << tv.id << "号电视机--"
      << (tv.mode == DVD ? "DVD" : "TV") << "模式--频道"
      << tv.channel_id << "--音量" << tv.volume;
  }
  friend void controller( Television& );
};

int Television::tv_num = 0;
int Television::dvd_num = 0;

void controller( Television& tv ) {
  int md {}, ch_id {}, vol {};
  cin >> md >> ch_id >> vol;
  tv.set_mode( md, ch_id ).adjust_vol( vol );
  cout << tv << endl;
}

int main()
{
  size_t n {}; cin >> n;
  auto arr = new Television[n] {};
  size_t t {}; cin >> t;
  while ( t-- ) {
    size_t offset {}; cin >> offset;
    controller( arr[offset - 1] );
  }
  cout << "播放电视的电视机数量为" << Television::num_tv() << endl
    << "播放DVD的电视机数量为" << Television::num_dvd() << endl;
}
  • 14
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值