声明
题解包含以下内容:
- (相对)高级的 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;
}