面向对象程序设计-04-引用与结构

声明

题解包含以下内容:

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

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

【id:19】【20分】A. 三数论大小(引用)

题目描述

输入三个整数,然后按照从大到小的顺序输出数值。

要求:定义一个函数,无返回值,函数参数是三个整数参数的引用,例如int &a, int &b, int &c。在函数内对三个参数进行排序。主函数调用这个函数进行排序。

要求:不能直接对三个整数进行排序,必须通过函数而且是引用的方法。

要求:输出必须在主函数进行。

输入

第一行输入t表示有t个测试实例

第二行起,每行输入三个整数

输入t行

输出

每行按照从大到小的顺序输出每个实例,三个整数之间用单个空格隔开

样例

输入样例1输出样例1
3
2 4 6
88 99 77
111 333 222
6 4 2
99 88 77
333 222 111

Answer

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

void my_sort(int& a, int& b, int& c)
{
  if (a < c)
    swap(a, c);
  if (a < b)
    swap(a, b);
  if (b < c)
    swap(b, c);
}

int main()
{
  size_t t = 0;
  cin >> t;
  while (t--) {
    int a = 0, b = 0, c = 0;
    cin >> a >> b >> c;
    my_sort(a, b, c);
    cout << a << " " << b << " " << c << endl;
  }

  return 0;
}

【id:134】【20分】B. 求最大值最小值(引用)

题目描述

编写函数void find(int *num,int n,int &minIndex,int &maxIndex),求数组num(元素为num[0],num[1],…,num[n-1])中取最小值、最大值的元素下标minIndex,maxIndex(若有相同最值,取第一个出现的下标。)

输入n,动态分配n个整数空间,输入n个整数,调用该函数求数组的最小值、最大值下标。

改变函数find功能不计分。

要求:在main函数中按样例格式输出结果,不能直接在find函数中输出。

输入

测试次数

每组测试数据一行:数据个数n,后跟n个整数

输出

每组测试数据输出两行,分别是最小值、最大值及其下标。具体格式见样例。多组测试数据之间以空行分隔。

样例

输入样例1输出样例1
2
5 10 20 40 -100 40
10 23 12 -32 4 6 230 100 90 -120 15
min=-100 minindex=3
max=40 maxindex=2

min=-120 minindex=8
max=230 maxindex=5

Answer

#include <bits/stdc++.h>
using std::cin, std::cout, std::endl, std::vector;
using std::distance, std::max_element, std::min_element;

void find(int *num, int n, int& min_index, int& max_index)
{
  min_index = distance(num, min_element(num, num + n));
  max_index = distance(num, max_element(num, num + n));
}

int main()
{
  size_t t {};
  cin >> t;
  while (t--) {
    size_t n {}; cin >> n;
    auto arr = vector<int>(n);
    for (auto& e : arr)
      cin >> e;
    int min_idx {}, max_idx {};
    find(arr.data(), n, min_idx, max_idx);
    cout << "min=" << arr[min_idx] << " minindex=" << min_idx
      << "\nmax=" << arr[max_idx] << " maxindex=" << max_idx
      << endl << endl;
  }

  return 0;
}

【id:133】【20分】C. 小票输入输出(结构体)

题目描述

现在人的消费习惯大多是刷卡消费,商家会通过POS机回执一个小票,包含商家名称、终端号、操作员、发卡方、有效期、卡号、交易时间、消费金额等信息,把商家信息定义为一个Struct结构,按照要求输出相应的格式小票。

输入

第一行输入消费次数(刷卡次数)

第二行依次输入小票包含的各种属性,最大长度不超过30.

第三行与第二行类似,以此类推。。。

输出

根据输入信息,依次输出各次刷卡信息$

样例

输入样例1输出样例1
2
TianHong 00001 01 CCB 21/06 6029071012345678 2016/3/13 1000.00
Cindy 00002 02 CCB 21/07 6029071055558888 2015/3/13 50.00
Name: TianHong
Terminal: 00001 operator: 01
Card Issuers: CCB Validity: 21/06
CardNumber: 6029********5678
Traded: 2016/3/13
Costs: $1000.00

Name: Cindy
Terminal: 00002 operator: 02
Card Issuers: CCB Validity: 21/07
CardNumber: 6029********8888
Traded: 2015/3/13
Costs: $50.00

Answer

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

struct Receipt {
  string name;
  string terminal;
  string operation;
  string card_issuer;
  string validity;
  string card_num;
  string traded;
  string costs;

  friend istream& operator>>(istream& is, Receipt& lhs) { // hidden friend function
    return is >> lhs.name >> lhs.terminal >> lhs.operation
      >> lhs.card_issuer >> lhs.validity >> lhs.card_num
      >> lhs.traded >> lhs.costs;
  }
  friend ostream& operator<<(ostream& os, const Receipt& lhs) {
    return os << "Name: " + lhs.name
      + "\nTerminal: " + lhs.terminal
      + " operator: " + lhs.operation
      + "\nCard Issuers: " + lhs.card_issuer
      + " Validity: " + lhs.validity
      + "\nCardNumber: " + lhs.card_num.substr(0, 4) + string(lhs.card_num.size() - 8, '*')
        + lhs.card_num.substr(lhs.card_num.size() - 4)
      + "\nTraded: " + lhs.traded
      + "\nCosts: $" + lhs.costs + '\n'
      << endl;
  }
};

int main()
{
  size_t t = 0;
  cin >> t;
  while (t--) {
    Receipt obj;
    cin >> obj;
    cout << obj;
  }

  return 0;
}

【id:20】【20分】D. 谁是老二(结构体)

题目描述

定义一个结构体,包含年月日,表示一个学生的出生日期。然后在一群学生的出生日期中找出谁的出生日期排行第二

要求:出生日期的存储必须使用结构体,不能使用其他类型的数据结构。

要求程序全过程对出生日期的输入、访问、输出都必须使用结构。

输入

第一行输入t表示有t个出生日期

每行输入三个整数,分别表示年、月、日

依次输入t个实例

输出

输出排行第二老的出生日期,按照年-月-日的格式输出

样例

输入样例1输出样例1
6
1980 5 6
1981 8 3
1980 3 19
1980 5 3
1983 9 12
1981 11 23
1980-5-3
输入样例2输出样例2
5
1980 4 1
1981 8 3
1980 3 31
1983 9 12
1981 11 23
1980-4-1

Answer

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

struct OJ_STRUCT {
  uint32_t year, month, day;

  auto operator<=>(const OJ_STRUCT& other) const {
    if (year == other.year)
      if (month == other.month)
        return day <=> other.day;
      else return month <=> other.month;
    else return year <=> other.year;
  }
  friend istream& operator>>(istream& is, OJ_STRUCT& lhs) { // hidden friend function
    return is >> lhs.year >> lhs.month >> lhs.day;
  }
  friend ostream& operator<<(ostream& os, const OJ_STRUCT& lhs) {
    return os << to_string(lhs.year) + '-' + to_string(lhs.month) + '-' + to_string(lhs.day);
  }
};

int main()
{
  size_t n {}; cin >> n;

  priority_queue<OJ_STRUCT, vector<OJ_STRUCT>, less<OJ_STRUCT>> heap;
  for (size_t _ = 0; _ < n; ++_) {
    OJ_STRUCT input; cin >> input;
    heap.push(move(input));
    while (heap.size() > 2)
      heap.pop();
  }
  cout << heap.top() << endl;

  return 0;
}

【id:21】【20分】E. 抄袭查找(结构体+指针+函数)

题目描述

已知一群学生的考试试卷,要求对试卷内容进行对比,查找是否有抄袭。

每张试卷包含:学号(整数类型)、题目1答案(字符串类型)、题目2答案(字符串类型)、题目3答案(字符串类型)

要求:使用结构体来存储试卷的信息。定义一个函数,返回值为一个整数,参数是两个结构体指针,函数操作是比较两张试卷的每道题目的答案,如果相同题号的答案相似度超过90%,那么就认为有抄袭,函数返回抄袭题号,否则返回0。相似度是指在同一题目中,两个答案的逐个位置上的字符两两比较,相同的数量大于等于任一个答案的长度的90%,就认为抄袭。

输入

第一行输入t表示有t张试卷

第二行输入第1张试卷的学生学号

第三行输入第1张试卷的题目1答案,最大长度不超过100

第四行输入第1张试卷的题目2答案,最大长度不超过100

第五行输入第1张试卷的题目3答案,最大长度不超过100

每张试卷对应4行输入

依次输入t张试卷的数据

输出

在一行中,把发现抄袭的两个学号和题目号输出,只输出第一次发现抄袭的题号,数据之间用单个空格隔开

如果发现是题目1抄袭,题目号为1,以此类推

输出顺序按照输入的学号顺序进行输出

样例

输入样例1输出样例1
5
2088150555
aabcdef11
ZZ887766dd
cc33447799ZZ
2088150333
abcdef00
AABBCCDDEE
ZZ668899cc
2088150111
AABBCCDDEE
ZZ668899cc
abcdef00
2088150222
AABBCFDDeE
ZZ889966dd
abcdef000
2088150444
aabcdef00
AABBCDDDEE
cc668899ZZ
2088150333 2088150444 2
2088150111 2088150222 3

Answer

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

struct OJ_STRUCT {
  int stu_id;
  array<string, 3> questions;

  friend istream& operator>>(istream& is, OJ_STRUCT& lhs) { // hidden friend function
    return is >> lhs.stu_id >> lhs.questions[0] >> lhs.questions[1] >> lhs.questions[2];
  }
};

int my_cmp(const OJ_STRUCT* const o1, const OJ_STRUCT* const o2)
{
  for (size_t i = 0; i < 3; ++i) {
    size_t duplicate_cnt = 0;
    for (size_t ii = 0; ii < min(o1->questions[i].size(), o2->questions[i].size()); ++ii)
      if (o1->questions[i][ii] == o2->questions[i][ii])
        ++duplicate_cnt;
    
    if (static_cast<double>(duplicate_cnt) / o1->questions[i].size() >= 0.9 ||
        static_cast<double>(duplicate_cnt) / o2->questions[i].size() >= 0.9)
      return i + 1;
  }
  return 0;
}

int main()
{
  size_t t {}; cin >> t;
  auto exam = vector<OJ_STRUCT>(t);
  for (auto& e : exam) cin >> e;
  for (size_t i = 0; i < exam.size(); ++i) { // 全排列
    for (size_t ii = i + 1; ii < exam.size(); ++ii) {
      if (const auto num = my_cmp(&exam[i], &exam[ii]);
          num != 0)
        cout << to_string(exam[i].stu_id) + " " + to_string(exam[ii].stu_id) + " " + to_string(num) << endl;
    }
  }

  return 0;
}
  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值