数组:买卖股票的最佳时机
# 题目描述
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
# 样例输入输出
样例1
输入:
7 1 5 3 6 4
输出:
5
样例2
输入:
7 6 4 3 1
输出:
0
#include <bits/stdc++.h>
using std::cout; using std::cin; using std::endl;
using std::vector;
class Solution {
public:
void run() {
vector<int> prices;
int prc;
while (cin >> prc) {
prices.push_back(prc);
}
int maxProfit = 0, minPrc = prices[0];
for (auto i = prices.begin(); i != prices.end(); ++i) {
if (*i > minPrc)
maxProfit = std::max(maxProfit, *i - minPrc);
else
minPrc = *i;
}
cout << maxProfit;
}
};
int main() {
Solution().run();
return 0;
}
无重复字符的最长子串
# 题目描述
给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。
s由英文字母,符号,数字组成。
解释:
输入:s = ”abcabcbb”
输出:3
因为无重复字符的最长子串是“abc”,所以其长度为3
# 样例输入输出
样例
输入:
pwwkew
输出:
3
样例2
输入:
aaaa
输出:
1
#include <bits/stdc++.h>
using std::cout; using std::cin; using std::endl;
using std::string; using std::map;
class Solution {
public:
void run() {
string str; cin >> str;
map<char, int> dic;
int maxLen = 0, left = 0;
for (int i = 0; i < (int)str.size(); ++i) {
if (dic.find(str[i]) == dic.end() || dic[str[i]] < left) {
// If dic doesn't have a key of str[i],
// insert it into dic and maxLen++.
dic[str[i]] = i;
}
else {
// If dic does have a key of str[i],
// update left (=dic[str[i]]+1) and maxLen (=i-left+1).
left = dic[str[i]] + 1;
dic[str[i]] = i;
}
maxLen = std::max(maxLen, i - left +1);
}
cout << maxLen;
}
};
int main() {
Solution().run();
return 0;
}
函数:不死神兔问题
# 题目描述
有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第 n 个月的兔子对数为多少?
输入描述:键盘输入任意一个正整数 n,n 的范围为 [1, 20]
输出描述:输出第 n 个月兔子的对数
# 样例输入输出
样例1
输入:
1
输出:
1
样例2
输入:
2
输出:
1
样例3
输入:
3
输出:
2
样例4
输入:
4
输出:
3
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
void run() {
int month; cin >> month;
int a = 0, b = 1;
while (month > 1) {
int tmp = a;
a = b;
b += tmp;
--month;
}
cout << b;
}
};
int main() {
Solution().run();
return 0;
}
数组元素翻转
# 题目描述
键盘随机输入 n 个整数,将这些数据保存到数组中,然后再将数组元素反转,按照格式输出数组元素。
输入描述:键盘随机输入 n 个整数输出描述:
输出描述:按照格式输出反转后数组中元素,每个元素中间使用逗号和空格隔开,整体使用中括号括起来。
例如:[60, 15, 7, 80, 12, 5]
# 样例输入输出
样例1
输入:
5 12 80 7 15 60
输出:
[60, 15, 7, 80, 12, 5]
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
static void run() {
vector<int> vec;
int tmp;
while (cin >> tmp) {
vec.push_back(tmp);
}
reverse(vec.begin(), vec.end());
for (int i = 0; i < vec.size(); ++i) {
if (i == 0) cout << "[";
cout << vec[i];
if (i == vec.size()-1) cout << "]";
else cout << ", ";
}
}
};
int main() {
Solution::run();
return 0;
}
计算走过的路程和反弹高度
# 题目描述
一个小球从 h 米高度自由落下,每次落地后反跳回原高度的一半再落下,求它在第 n 次落地时共经过了多少米?第 n 次返弹多高?
输入描述:输入小球下落的高度h(double型)和落地的次数n(int型)(先输入小球初始高度再输入反弹次数)
输出描述:输出小球第 n 次落地时经过的距离和第 n 次反弹的高度(保留小数点后1位)
# 样例输入输出
样例1
输入:
100 1
输出:
100.0 50.0
样例2
输入:
100.0 3
输出:
250.0 12.5
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
static void run() {
double h; int n; cin >> h >> n;
double height = h/2, sum = h;
for (int i = 1; i < n; ++i) {
sum += height * 2;
height /= 2;
}
printf("%.1f %.1f", sum, height);
}
};
int main() {
Solution::run();
return 0;
}
指针:合并两个有序链表
# 题目描述
给定两个有序数值数组,要求先按所给数值建立两个链表,链表为升序链表。将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
需要按以下结构体建立链表
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
输入:l1=[1,2,3],l2 = [1,3,4]
输出:[1,1,2,3,4,4]
提示:输入输出的标准模式请见样例输入输出,输入时可以通过两个while循环构造两个链表,其中一行为一个链表,判断当遇到‘\n’时结束循环,链表构造完成。
提示:输出的最后一个数字后无“ ”
# 样例输入输出
样例1
输入:
1 2 4
1 3 4
输出:
1 1 2 3 4 4
#include <bits/stdc++.h>
using namespace std;
typedef struct ListNode {
int val;
ListNode *next;
ListNode(): val(0), next(nullptr) {}
ListNode(int x, ListNode* next= nullptr) : val(x), next(next) {}
} ListNode;
class Solution {
public:
static void run() {
// Handle input stream.
string str, strNum;
getline(cin, str);
stringstream ss(str);
vector<int> vec1, vec2;
while (getline(ss, strNum, ' ')) // Let vec1 store elements of list1.
vec1.push_back(stoi(strNum));
getline(cin, str);
stringstream ss2(str);
while (getline(ss2, strNum, ' ')) // Let vec2 store elements of list2.
vec2.push_back(stoi(strNum));
// Initialize two linked lists.
ListNode list1[vec1.size()];
ListNode list2[vec2.size()];
for (int i = 0; i < vec1.size(); ++i)
list1[i] = ListNode(vec1[i]);
for (int i = 0; i < vec1.size() - 1; ++i)
list1[i].next = &list1[i+1];
for (int i = 0; i < vec2.size(); ++i)
list2[i] = ListNode(vec2[i]);
for (int i = 0; i < vec2.size() - 1; ++i)
list2[i].next = &list2[i+1];
// Combine two linked lists;
ListNode* p1 = &list1[0]; ListNode* p2 = &list2[0];
auto head = ListNode(-1); ListNode* p3 = &head;
while (p1 && p2) {
if (p1->val <= p2->val) { p3->next = p1; p1 = p1->next; p3 = p3->next; }
else { p3->next = p2; p2 = p2->next; p3 = p3->next; }
}
if (p1) p3->next = p1;
if (p2) p3->next = p2;
ListNode* res = (&head)->next;
for (; res; res = res->next)
{ cout << res->val; if (res->next) cout << " "; }
}
};
int main () {
Solution::run();
return 0;
}
指针:验证回文串
# 题目描述
给定一个字符串,验证它是否是回文串,回文字符串就是正向和反向看完全相同的字符串,只考虑字母和数字字符,不考虑标点符号,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 :
输入: "A man, a plan, a canal: Panama"
输出: true
解释:"amanaplanacanalpanama" 是回文串
示例 :
输入: "race a car"
输出: false
解释:"raceacar" 不是回文串
提示:可以先对字符串进行处理,去除标点符号将大写字母全部转换为小写
# 样例输入输出
样例1
输入:
A man, a plan, a canal: Panama
输出:
true
样例2
输入:
race a car
输出:
false
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
static void run() {
string str; cin >> str;
// Handle the input string.
for (auto i = str.begin(); i != str.end(); ) {
if (!isalpha(*i)) { i = str.erase(i); continue; }
if (isupper(*i)) *i = static_cast<char>(tolower(*i));
i = i + 1;
}
// Judge whether str is palindrome or not.
for (int i = 0, j = static_cast<int>(str.size()) - 1; i != j && i - 1 != j ; ++i, --j) {
if (str[i] == str[j]) continue;
else { cout << "false" << endl; return; }
}
cout << "true" << endl;
}
};
int main () {
Solution::run();
return 0;
}
放大位图
# 题目描述
位图(bitmap),亦称为点阵图像或栅格图像,是由称作像素(图片元素)的单个点组成的。这些点可以进行不同的排列和染色以构成图样。当放大位图时,可以看见赖以构成整个图像的无数单个方块。扩大位图尺寸的效果是增大单个像素,从而使线条和形状显得参差不齐。然而,如果从稍远的位置观看它,位图图像的颜色和形状又显得是连续的。
现在请你设计一个程序将原来n*n的图像放大k倍。
例如,将2*2的点阵放大2倍
1 0
0 1
经过放大后新的点阵为
1 1 0 0
1 1 0 0
0 0 1 1
0 0 1 1
输出样例的每个数字后用空格隔开
# 样例输入输出
样例1
输入:
2 2
1 0
0 1
输出:
1 1 0 0
1 1 0 0
0 0 1 1
0 0 1 1
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
static void run() {
int n, k; cin >> n >> k;
vector<vector<int>> matrix(n, vector<int>(n));
vector<vector<int>> ret;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
cin >> matrix[i][j];
}
for (int i = 0; i < n; i++) {
vector<int> tmp(n * k);
for (int j = 0; j < n; j++) {
for (int kk = 0; kk < k; kk++) {
tmp[j * k + kk] = matrix[i][j];
}
}
for (int kk = 0; kk < k; kk++)
ret.push_back(tmp);
}
for (const auto & vec : ret) {
for (const auto & i : vec)
cout << i << " ";
cout << endl;
}
}
};
int main () {
Solution::run();
return 0;
}
批量注册用户
# 题目描述
小明想要尝试注册多个用户名,用户名的规则如下:
用户名长度不能少于6位,不能多于12位;用户名必须由字母(大小写均可)构成;同一个用户名不能被重复注册;
请你编写一个程序判断小明的n个用户名是否创建成功。
如果创建成功输出:registration complete。
如果长度不合法输出:illegal length。
若长度不合法且字符也不合法输出:illegal length。
如果字符不合法输出:illegal charactor。
如果用户名已存在输出:acount existed。
# 样例输入输出
样例1
输入:
5
1
abcd
abcdef
abcdef
abc1ef
输出:
illegal length
illegal length
registration complete
acount existed
illegal charactor
只要长度不合法 -> illegal length
长度合法 但是字符不合法 -> illegal charactor
用户名存在 -> acount existed
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
static void run() {
int n; cin >> n;
vector<string> inputStr(n);
set<string> st;
for (int i = 0; i < n; i++)
cin >> inputStr[i];
for (int i = 0; i < n; i++) {
if (inputStr[i].size() < 6 || inputStr[i].size() > 12) { cout << "illegal length" << endl; continue; }
bool flag = false;
for (const auto & chr : inputStr[i]) {
if ((chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z'))
continue;
cout << "illegal charactor" << endl; flag = true; break;
}
if (flag) continue;
if (st.find(inputStr[i]) == st.end()) { cout << "registration complete" << endl; st.insert(inputStr[i]); }
else cout << "acount existed" << endl;
}
}
};
int main () {
Solution::run();
return 0;
}
类与对象的定义
# 题目描述
要求设计一个立方体类(Cube)
成员变量有:长(length)、宽(width)、高(height),都为int类型;
成员方法有:输入输出函数、获取表面积的方法(getArea),获取体积的方法(getVolume)。
输入描述:输入立方体的长、宽、高
输出描述:输出立方体的长、宽、高、面积、体积
要求:长宽高均为整数类型,输入/输出的各项之间使用空格隔开。
# 样例输入输出
样例1
输入:
3 4 5
输出:
3 4 5 94 60
#include <bits/stdc++.h>
using namespace std;
class Cube {
private:
int length, width, height;
public:
void Input() {
cin >> length >> width >> height;
}
int getArea() {
return (length * width + width * height + height * length) * 2;
}
int getVolume() {
return length * width * height;
}
void Output() {
cout << length << " " << width << " " << height << " " << getArea() << " " << getVolume() << endl;
}
};
int main () {
auto cube = Cube();
cube.Input();
cube.Output();
return 0;
}
类和对象:删除链表的重复节点
# 题目描述
给定一个随机长度的数值数组,要求构造成链表并删除其中有重复的元素,使每个元素只出现一次。返回删除好的链表。按输入顺序,删除第一次之后出现的结点,按原顺序返回
输入描述:输入一系列数值,不一定有序
输出描述:删除重复结点后的链表。
# 样例输入输出
样例1
输入:
1 5 3 1 9
输出:
1 5 3 9
#include <bits/stdc++.h>
using namespace std;
typedef struct Node {
int val;
Node * next;
Node(int x) : val(x), next(nullptr) {}
Node(int x, Node * n) : val(x), next(n) {}
} Node;
class Solution {
private:
set<int> se;
public:
void Run() {
// Prepare numbers of link list.
string str; getline(cin, str);
stringstream ss(str);
string subStr;
vector<int> vec;
while (getline(ss, subStr, ' '))
vec.push_back(stoi(subStr));
// Use set to erase repeated elements.
Node * head = new Node(-1);
Node * p = head;
for (const auto & i : vec) {
if (se.find(i) != se.end()) continue;
se.insert(i);
p->next = new Node(i);
p = p->next;
}
for (Node * i = head; i->next != nullptr; i = i->next)
cout << i->next->val << " ";
}
};
int main () {
Solution().Run();
return 0;
}
类和对象:运算符重载
# 题目描述
定义一个日期类Date,包含年、月、日三个数据成员,请实现重载自增运算符(++),实现日期的自增。
输入描述:2020 11 11,对应年,月,日
输出描述:2020 年11月12日,对应明天的年,月,日
需要注意特殊情况比如(月末,年末,平年,闰年判断)例如:
输入:2020 12 31
输出:2021年1月1日
# 样例输入输出
样例1
输入:
2021 12 11
输出:
2021年12月12日
#include <bits/stdc++.h>
using namespace std;
class Date {
private:
int year;
int month;
int day;
vector<int> mon30 = {4, 6, 9, 11};
vector<int> mon31 = {1, 3, 5, 7, 8, 10};
void dateCheck() {
// Special Case: 2月份 闰年 平年
if (month == 2) {
if ((year % 100 == 0 && year % 400 == 0) || (year % 4 == 0)) {
if (day > 29) { month++; day %= 29; return; }
} else {
if (day > 28) { month++; day %= 28; return; }
}
}
// Special Case: 31天的月份 30天的月份
if (month == 12) {
if (day > 31) { year++; month = 1; day %= 31; return; }
}
if (find(mon30.begin(), mon30.end(), month) != mon30.end()) {
if (day > 30) { month++; day %= 30; return; }
}
if (find(mon31.begin(), mon31.end(), month) != mon31.end()) {
if (day > 31) { month++; day %= 31; return; }
}
}
public:
Date(int y, int m, int d) : year(y), month(m), day(d) {}
void operator++(int) {
day++;
dateCheck();
}
void Print() const {
cout << year << "年" << month << "月" << day << "日" << endl;
}
};
int main() {
int y, m, d; cin >> y >> m >> d;
Date dt = Date(y, m, d);
dt++;
dt.Print();
return 0;
}
类和对象:对象数组
# 题目描述
构建一个Book类,有4个私有数据成员:书名、作者、qu和price(均为int型),将qu进行初始化,
同时price被始化为qu的10倍。建立一个有5个元素的对象数组,顺序显示每个对象数组中元素的信息;
定义对象指针,通过指针访问对象数组,逆序显示对象数组中元素的信息。书名、作者、qu的信息从键盘输入
输入描述: 5个对象数组元素的值
输出描述: 顺序显示对象数组中各对象的值 ,各参数中间以空格隔开
逆序显示对象数组中各对象的值 ,各参数中间以空格隔开
# 样例输入输出
## 样例1
输入:
C语言程序设计 苏小红 2
C++程序设计 刘丽华 3
Python机器学习 范淼 4
数据结构与算法 徐凤生 3
大话数据结构 程杰 2
输出:
书名:C语言程序设计 作者:苏小红 价格:20
书名:C++程序设计 作者:刘丽华 价格:30
书名:Python机器学习 作者:范淼 价格:40
书名:数据结构与算法 作者:徐凤生 价格:30
书名:大话数据结构 作者:程杰 价格:20
使用指针逆序显示的结果为
书名:大话数据结构 作者:程杰 价格:20
书名:数据结构与算法 作者:徐凤生 价格:30
书名:Python机器学习 作者:范淼 价格:40
书名:C++程序设计 作者:刘丽华 价格:30
书名:C语言程序设计 作者:苏小红 价格:20
#include <bits/stdc++.h>
using namespace std;
class Book {
private:
string name;
string author;
int qu;
int price;
public:
Book(string nm, string auth, int qu) : name(std::move(nm)), author(std::move(auth)), qu(qu), price(qu*10) {}
void Print() const {
cout << "书名:" << name << " " << "作者:" << author << " " << "价格:" << price << endl;
}
};
int main() {
vector<Book> books;
for (int i = 0; i < 5; i++) {
string name;
string author;
int qu;
cin >> name >> author >> qu;
books.emplace_back(name, author, qu);
}
// Print out 5 books.
for (const auto & book : books)
book.Print();
reverse(books.begin(), books.end());
cout << "使用指针逆序显示的结果为" << endl;
for (const auto & book : books)
book.Print();
return 0;
}
类和对象:多继承
# 题目描述
1、定义日期“Date”类,类中包含数据成员年、月、日,成员函数包括构造函数(只有带参的构造函数),设置日期函数,显示日期函数
2、定义时间“Time”类,数据成员包括时、分、秒。成员函数的要求与date类相同
3、定义日期时间型“Date_Time”类
⑴公有继承Date类及Time类;
⑵不增加数据成员;
⑶增加日期时间处理成员函数,包括初始化日期时间、设置日期时间、显示日期时间等。
4、每个类都要求重载>> 和<<运算符用于对日期时间的输入和输出
5.对Date_Time,重载>运算符,用于判断两个时间大小。
6. 编写main()函数进行测试。在主函数中,输入两个Date_Time类的数据,对两个日期时间进行比较,输出较小的一个。
# 样例输入输出
样例1
输入:
2022 4 16 18 30 31 2022 4 16 18 30 35
输出:
2022-4-16 18:30:31
#include <bits/stdc++.h>
using namespace std;
class Date {
public:
int year;
int month;
int day;
public:
Date(int y, int m, int d) : year(y), month(m), day(d) {};
friend ostream & operator<<(ostream & output, const Date & date) {
output << to_string(date.year) + "-" + to_string(date.month) + "-" + to_string(date.day);
return output;
}
friend istream & operator>>(istream & input, Date & date) {
input >> date.year >> date.month >> date.day;
return input;
}
};
class Time {
public:
int hour;
int minute;
int second;
public:
Time(int h, int m, int s) : hour(h), minute(m), second(s) {};
friend ostream & operator<<(ostream & output, const Time & time) {
output << to_string(time.hour) + ":" + to_string(time.minute) + ":" + to_string(time.second);
return output;
}
friend istream & operator>>(istream & input, Time & time) {
input >> time.hour >> time.minute >> time.second;
return input;
}
};
class Date_Time : public Date, public Time {
public:
Date_Time() : Date(0, 0, 0), Time(0, 0, 0) {}
Date_Time(int y, int m, int d, int h, int min, int s) : Date(y, m, d), Time(h, min, s) {}
friend ostream & operator<<(ostream & output, const Date_Time & dateTime) {
output << to_string(dateTime.year) + "-" + to_string(dateTime.month) + "-" + to_string(dateTime.day);
output << " ";
output << to_string(dateTime.hour) + ":" + to_string(dateTime.minute) + ":" + to_string(dateTime.second);
return output;
}
friend istream & operator>>(istream & input, Date_Time & dateTime) {
input >> dateTime.year >> dateTime.month >> dateTime.day;
input >> dateTime.hour >> dateTime.minute >> dateTime.second;
return input;
}
bool operator>(Date_Time & time2) {
if (this->year < time2.year) return false;
else if (this->year > time2.year) return true;
if (this->month < time2.month) return false;
else if (this->month > time2.month) return true;
if (this->day < time2.day) return false;
else if (this->day > time2.day) return true;
if (this->hour < time2.hour) return false;
else if (this->hour > time2.hour) return true;
if (this->minute < time2.minute) return false;
else if (this->minute > time2.minute) return true;
if (this->second < time2.second) return false;
else if (this->second > time2.second) return true;
return false;
}
};
int main() {
Date_Time dateTime1, dateTime2;
cin >> dateTime1 >> dateTime2;
if (dateTime1 > dateTime2)
cout << dateTime2;
else
cout << dateTime1;
return 0;
}
类和对象:继承与派生
# 题目描述
把描述直角坐标系上的一个点类作为基类,派生出描述一条直线的类和描述一个三角形的类。定义成员函数求出两点间的距离和三角形的面积。点的坐标均为int型
提示:先定义描述点 的类Point;类Line继承自Point类,一个直线有两个端点,所以他在点类的基础上新增一组点的坐标(x2,y2);三角形类 Triangle 再直线的基础上再新增一组点的坐标(x3,y3)求出三角形的面积。具体要求如下
(1)定义点类Point
保护数据成员 x1,y1
共有构造函数Point(int x1,int y1)用于初始化x1,y1
(2)定义直线类Line
保护数据成员x2,y2
共有构造函数Line ( int x1,int y1 ,int x2,int y2)用于初始化x2,y2,以及父类x1,y1
(3)定义三角形Triangle
私有数据成员 x3,y3
私有数据成员 area
共有构造函数Triangle( int x1,int y1 ,int x2,int y2,int x3 ,int y3) 用于初始化x3,y3 以及父类x1,y1,x2,y2
void area():求三角形面积的功能函数
void print():输出三个点的坐标和面积
输入描述:输入6个int型数值(x1,y1,x2,y2,x3,y3)
输出描述:第一行输出三个点的坐标,第二行输出面积
# 样例输入输出
样例1
输入:
1 1 4 1 4 5
输出:
(1,1)(4,1)(4,5)
6
#include <bits/stdc++.h>
using namespace std;
class Point {
protected:
int x1, y1;
public:
Point(int x, int y) : x1(x), y1(y) {}
};
class Line : protected Point {
protected:
int x2, y2;
public:
Line(int x1, int y1, int x2, int y2) : Point(x1, y1), x2(x2), y2(y2) {}
};
class Triangle : private Line {
private:
int x3, y3;
double area;
public:
Triangle(int x1, int y1, int x2, int y2, int x3, int y3) : Line(x1, y1, x2, y2), x3(x3), y3(y3), area(0) {}
void calcArea() {
area = abs((x1*y2 - x2*y1) + (x2*y3 - x3*y2) + (x3*y1 - x1*y3)) / 2.0;
}
void print() {
cout << "(" + to_string(x1) + "," + to_string(y1) + ")";
cout << "(" + to_string(x2) + "," + to_string(y2) + ")";
cout << "(" + to_string(x3) + "," + to_string(y3) + ")" << endl;
cout << area << endl;
}
};
int main() {
int x1, y1, x2, y2, x3, y3;
cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
auto triangle = Triangle(x1, y1, x2, y2, x3, y3);
triangle.calcArea();
triangle.print();
return 0;
}
重载运算符练习
# 题目描述
定义一个RMB类Money,包括元角分三个数据成员,重载运算符'+'和'-',实现货币的加减运算。
# 例如:
输入一组元角分:
2 3 4
3 7 3
输出:
和:6元0角7分
差:-1元3角9分
#include <bits/stdc++.h>
using namespace std;
class RMB {
protected:
int money;
public:
explicit RMB(int mon) : money(mon) {}
RMB operator+(const RMB & rmb) const {
auto ret = RMB(money + rmb.money);
return ret;
}
RMB operator-(const RMB & rmb) const {
auto ret = RMB(money - rmb.money);
return ret;
}
void print() const {
if (money >= 0)
cout << money / 100 << "元" << (money % 100) / 10 << "角" << money % 10 << "分";
else {
int monTemp = -money;
cout << "-" << monTemp / 100 << "元" << (monTemp % 100) / 10 << "角" << monTemp % 10 << "分";
}
}
};
int main() {
int a, b, c;
vector<RMB> rmbs;
for (int i = 0; i < 2; i++) {
cin >> a >> b >> c;
rmbs.emplace_back(RMB(a*100 + b*10 + c));
}
auto res1 = rmbs[0] + rmbs[1];
auto res2 = rmbs[0] - rmbs[1];
cout << "和:"; res1.print(); cout << endl;
cout << "差:"; res2.print(); cout << endl;
return 0;
}
继承
# 题目描述
以点(Point)类为基类,重新定义圆类(Circle)。在圆类中实现一个 isPointerInCircle方法,该方法传入一个点类对象,判断点和圆的关系,并在该方法中输出。
点类(Point):
成员变量:x轴坐标(int x) y轴坐标(int y)
圆类(Circle)继承自点类(Point),以Point为圆心:
成员变量: 半径(double radius)
成员方法:判断点和圆关系的方法(isPointerInCircle)
点和圆的关系(最终输出为以下三种关系之一):
点在圆外
点在圆上
点在圆内
输入描述:
0 0
1 1 1.0
(第一行为要判断的点的横纵坐标,第二行前两个参数为圆的圆心坐标,第三个参数为圆的半径)
输出描述:
点在圆外
# 样例输入输出
样例1
输入:
0 0
1 1 1.0
输出:
点在圆外
#include <bits/stdc++.h>
using namespace std;
class Point {
public:
int x;
int y;
Point(int a, int b) : x(a), y(b) {}
};
class Circle : public Point {
public:
double radius;
public:
Circle(int a, int b, double c) : Point(a, b), radius(c) {}
void isPointerInCircle(const Point & p) const {
double distance = sqrt(pow(fabs(x - p.x), 2) + pow(fabs(y - p.y), 2));
if (distance - radius > DBL_EPSILON)
cout << "点在圆外";
else if (distance - radius >= 0 && distance - radius <= DBL_EPSILON)
cout << "点在圆上";
else
cout << "点在圆内";
}
};
int main() {
int pX, pY; cin >> pX >> pY; auto p = Point(pX, pY);
double r; cin >> pX >> pY >> r; auto circle = Circle(pX, pY, r);
circle.isPointerInCircle(p);
return 0;
}
继承组合
# 题目描述
声明Teacher(教师)类为基类,数据成员包括:姓名,性别。成员函数为构造析构函数
Professor(教授)类为Teacher类的派生类。
另有一个BirthDate(生日)类,数据成员包含year,month,day等数据成员。可以将教授的生日信息加入到Professor类的声明中作为Professor的对象成员。
在主函数中,定义Professor类对象时给定初始值,然后给定一个新的BirthDate类对象,更新原对象中的生日数据并输出。
输入描述:
第一行依次输入构造Professor对象的各项初始数据
第二行输入为新的BirthDate对象的数值
输出描述
更新原有的professor对象的birthday数据并输出
# 样例输入输出
样例1
输入:
zhangsan M 1999 7 14
2001 5 21
输出:
name: zhangsan
sex: M
birthdate: 2001/5/21
#include <bits/stdc++.h>
using namespace std;
class Teacher {
public:
string name;
string gender;
public:
Teacher(string & n, string & g) : name(n), gender(g) {}
};
class BirthDate {
public:
int year;
int month;
int day;
BirthDate(int y, int m, int d) : year(y), month(m), day(d) {}
};
class Professor : public Teacher {
public:
BirthDate bd;
Professor(string & n, string & g, int y, int m, int d) :
Teacher(n, g), bd(BirthDate(y, m, d)) {}
void print() const {
cout << "name: " << name << endl;
cout << "sex: " << gender << endl;
cout << "birthdate: " << bd.year << "/" << bd.month << "/" << bd.day << endl;
}
};
int main() {
string n, g; int y, m, d;
cin >> n >> g >> y >> m >> d; auto prof = Professor(n, g, y, m, d);
cin >> y >> m >> d; prof.bd = BirthDate(y, m, d);
prof.print();
return 0;
}
多重继承
# 题目描述
分别定义Teacher(教师)类和Cadre(干部)类,采用多重继承方式由这两个类派生出新类Teacher_Cadre(教师兼干部)类。要求:
1、Teacher类中包含数据成员 姓名、年龄、性别、职称(title)。
2、Cadre类中包含数据成员 姓名、年龄、性别、职务(post)。
3、Teacher_Cadre类中还包含数据成员工资(wages)。
4.两个基类中的姓名、年龄、性别 数据成员用相同的名字,在引用这些数据成员时,指定作用域。
5、在派生类Teacher_Cadre 的成员函数show 中调用Teacher类中的display 函数,输出姓名、年龄、性别、职称,然后再用cout语句输出职务与工资。
输入描述:
输入3个教师兼干部内容分别构造3个类
输出描述:
输出工资最高的一位教师兼干部的各项信息
# 样例输入输出
样例1
输入:
zhangsan 30 M teacher assistent 3456.2
lisi 34 M professor assistent 4589.5
wangwu 56 M professor manager 8569.5
输出:
name: wangwu
age: 56
sex: M
title: professor
post: manager
wage: 8569.5
#include <bits/stdc++.h>
using namespace std;
class Teacher {
public:
string name;
string gender;
int age;
string title;
public:
Teacher(string & n, string & g, int age, string & t) :
name(n), gender(g), age(age), title(t) {}
void display() const {
cout << "name: " << name << endl;
cout << "age: " << age << endl;
cout << "sex: " << gender << endl;
cout << "title: "<< title << endl;
}
};
class Cadre {
public:
string name;
string gender;
int age;
string post;
Cadre(string & n, string & g, int age, string & p) :
name(n), gender(g), age(age), post(p) {}
};
class Teacher_Cadre : public Teacher, public Cadre {
public:
double wages;
public:
Teacher_Cadre(string & n, string & g, int age, string & t, string & p, double w) :
Teacher(n, g, age, t), Cadre(n, g, age, p), wages(w) {}
void show() const {
this->Teacher::display();
cout << "post: " << post << endl;
cout << "wage: " << wages << endl;
}
};
int main() {
vector<Teacher_Cadre> people;
string n, g, t, p; int age; double wage;
for (int i = 0; i < 3; i++) {
cin >> n >> age >> g >> t >> p >> wage;
people.emplace_back(Teacher_Cadre(n, g, age, t, p, wage));
}
// Find the highest wage.
int ind = 0; double highest = people[0].wages;
for (int i = 0; i < people.size(); i++) {
if (highest < people[i].wages) {
highest = people[i].wages;
ind = i;
}
}
people[ind].show();
return 0;
}
多态性
# 题目描述
完成以下代码,实现简单的计算器功能。
定义一个BaseCalculator类,包括数据成员m_A,m_B,定义成员函数为虚函数getResult(),在基类中无需实现。
定义AddCalculator,SubCalculator,MultiplicationCalculator ,DivisionCalculator为加、减、乘、除四种计算器类,继承自BaseCalculator类,并在每个类中实现getResult()方法进行不同类型的运算。
在主函数中定义一个BaseCalculator类型的指针,分别指向四种不同计算功能的四各类对象进行输出。
输入描述:输入两个整形数字m_A,m_B
输出描述:
第一行为加法结果
第二行为减法结果
第三行为乘法结果
第四行为除法结果
# 样例输入输出
样例1
输入:
6 2
输出:
8
4
12
3
#include <bits/stdc++.h>
using namespace std;
class BaseCalculator {
protected:
int m_A;
int m_B;
public:
BaseCalculator(int a, int b) : m_A(a), m_B(b) {}
virtual int getResult() {}
};
class AddCalculator : public BaseCalculator {
public:
AddCalculator(int i, int i1) : BaseCalculator(i, i1) {}
int getResult() override {
return m_A + m_B;
}
};
class SubCalculator : public BaseCalculator {
public:
SubCalculator(int i, int i1) : BaseCalculator(i, i1) {}
int getResult() override {
return m_A - m_B;
}
};
class MultiplicationCalculator : public BaseCalculator {
public:
MultiplicationCalculator(int i, int i1) : BaseCalculator(i, i1) {}
int getResult() override {
return m_A * m_B;
}
};
class DivisionCalculator : public BaseCalculator {
public:
DivisionCalculator(int i, int i1) : BaseCalculator(i, i1) {}
int getResult() override {
return m_A / m_B;
}
};
int main() {
int a, b; cin >> a >> b;
BaseCalculator * baseCalc;
baseCalc = new AddCalculator(a, b);
cout << baseCalc->getResult() << endl;
baseCalc = new SubCalculator(a, b);
cout << baseCalc->getResult() << endl;
baseCalc = new MultiplicationCalculator(a, b);
cout << baseCalc->getResult() << endl;
baseCalc = new DivisionCalculator(a, b);
cout << baseCalc->getResult() << endl;
}
虚函数
# 题目描述
写一个程序,定义抽象基类Shape,由他派生出3个派生类:Circle(圆类),Rectangle(矩形),Triangle(三角形)。用虚函数分别计算几种图形的面积,并求他们的和。
输入描述:
第一行为圆的半径
第二行为矩形的长,宽
第三行为三角形的底和高
输出描述:
第一行为圆形的面积
第二行为矩形的面积
第三行为三角形的面积
第四行为三个图形面积和
# 样例输入输出
样例2
输入:
2
3 4
6 8
输出:
Circlearea=12.56
Rectanglearea=12
Trianglearea=24
Area sum=48.56
#include <bits/stdc++.h>
using namespace std;
class Shape {
public:
double circleRadius{};
double recWidth{}, recHeight{};
double triBase{}, triHeight{};
public:
virtual double getCircleArea() {};
virtual double getRecArea() {};
virtual double getTriArea() {};
};
class Circle : virtual public Shape {
public:
double getCircleArea() override {
return 3.14 * circleRadius * circleRadius;
}
};
class Rectangle : virtual public Shape {
public:
double getRecArea() override {
return recWidth * recHeight;
}
};
class Triangle : virtual public Shape {
public:
double getTriArea() override {
return 0.5 * triBase * triHeight;
}
};
int main() {
auto circle = new Circle();
cin >> circle->circleRadius;
auto rectangle = new Rectangle();
cin >> rectangle->recWidth >> rectangle->recHeight;
auto triangle = new Triangle();
cin >> triangle->triBase >> triangle->triHeight;
cout << "Circlearea=" << circle->getCircleArea() << endl;
cout << "Rectanglearea=" << rectangle->getRecArea() << endl;
cout << "Trianglearea=" << triangle->getTriArea() << endl;
cout << "Area sum=" << circle->getCircleArea() + rectangle->getRecArea() + triangle->getTriArea() << endl;
}
字符串A
# 题目描述
利用指针实现复制一个字符串的指定位数成为一个新的字符串 。例如样例输入输出中helloNKCS中,N为第6个字符,从N开始复制N及之后的NKCS作为新字符串。
输入描述:
第一行输入 复制开始的位置 ,第二行输入一个字符串
输出描述:
从开始位置截取之后的字符串作为新字符串并输出
# 样例输入输出
样例1
输入:
6
helloNKCS
输出:
NKCS
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
static void run() {
int ind; cin >> ind;
string s; cin >> s;
for (int i = ind-1; i < s.length(); i++) {
cout << s[i];
}
}
};
int main() {
Solution::run();
}
类和对象B
# 题目描述
分别定义Teacher(教师)类和Cadre(干部)类,采用多重继承方式由这两个类派生出新类Teacher_Cadre(教师兼干部)类。要求:
1、Teacher类中包含数据成员 姓名、年龄、性别、职称(title)。
2、Cadre类中包含数据成员 姓名、年龄、性别、职务(post)。
3、Teacher_Cadre类中还包含数据成员工资(wages)。
4.两个基类中的姓名、年龄、性别 数据成员用相同的名字,在引用这些数据成员时,指定作用域。
5、在派生类Teacher_Cadre 的成员函数show 中调用Teacher类中的display 函数,输出姓名、年龄、性别、职称,然后再用cout语句输出职务与工资。
输入描述:
输入3个教师兼干部内容分别构造3个类
输出描述:
输出工资最低的一位教师兼干部的各项信息,中间以空格分开
# 样例输入输出
样例1
输入:
zhangsan 30 M teacher assistent 3456.2
lisi 34 M professor assistent 4589.5
wangwu 56 M professor manager 8569.5
输出:
zhangsan 30 M teacher assistent 3456.2
#include <bits/stdc++.h>
using namespace std;
class Teacher {
public:
string name;
string gender;
int age;
string title;
public:
Teacher(string & n, string & g, int age, string & t) :
name(n), gender(g), age(age), title(t) {}
void display() const {
// cout << "name: " << name << endl;
// cout << "age: " << age << endl;
// cout << "sex: " << gender << endl;
// cout << "title: "<< title << endl;
cout << name << " " << age << " " << gender << " " << title << " ";
}
};
class Cadre {
public:
string name;
string gender;
int age;
string post;
Cadre(string & n, string & g, int age, string & p) :
name(n), gender(g), age(age), post(p) {}
};
class Teacher_Cadre : public Teacher, public Cadre {
public:
double wages;
public:
Teacher_Cadre(string & n, string & g, int age, string & t, string & p, double w) :
Teacher(n, g, age, t), Cadre(n, g, age, p), wages(w) {}
void show() const {
this->Teacher::display();
// cout << "post: " << post << endl;
// cout << "wage: " << wages << endl;
cout << post << " " << wages << endl;
}
};
int main() {
vector<Teacher_Cadre> people;
string n, g, t, p; int age; double wage;
for (int i = 0; i < 3; i++) {
cin >> n >> age >> g >> t >> p >> wage;
people.emplace_back(Teacher_Cadre(n, g, age, t, p, wage));
}
// Find the highest wage.
int ind = 0; double lowest = people[0].wages;
for (int i = 0; i < people.size(); i++) {
if (lowest > people[i].wages) {
lowest = people[i].wages;
ind = i;
}
}
people[ind].show();
return 0;
}
数组排序
# 题目描述
编写程序完成以下功能:
由键盘输入一系列数字组成一个数组,将改串数字从小到大进行排序操作,输出排好序的数组。
输入描述:
键盘随意输入一串数字
输出描述:
将输入的数字排序后进行输出。
# 样例输入输出
样例1
输入:
4 7 2 6 0 3 5 7 9
输出:
0 2 3 4 5 6 7 7 9
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
static void run() {
vector<int> vec;
int temp;
while (cin >> temp) {
vec.push_back(temp);
}
sort(vec.begin(), vec.end(), less<int>());
for (int i = 0; i < vec.size(); i++) {
cout << vec[i];
if (i != vec.size()-1) cout << " ";
}
}
};
int main() {
Solution::run();
}
附加题
# 题目描述
编写程序实现以下功能:
两两交换链表中的相邻节点,例如一个链表长度为4,1,2位节点进行交换,3,4位节点进行交换,输出交换后的链表。
1->2->3->4
变换为:
2->1->3->4
输入描述:
输入一系列数字代表一个链表
输出描述:
两两翻转后输出
# 样例输入输出
样例1
输入:
1 2 3 4
输出:
2 1 4 3
#include <bits/stdc++.h>
using namespace std;
typedef struct Node {
int val;
Node * next;
Node() : val(0), next(nullptr) {}
explicit Node(int v) : val(v), next(nullptr) {}
explicit Node(int v, Node * n) : val(v), next(n) {}
} Node;
class Solution {
public:
static void run() {
// 根据输入构建链表
Node * head = new Node(-1);
int temp;
Node * h = head;
while (cin >> temp) {
Node * node = new Node(temp);
h->next = node;
h = h->next;
}
// 两两交换相邻结点
h = head;
while (h && h->next) {
// 后面两个结点都存在时进行翻转
if (h->next && h->next->next) {
Node * node1 = h->next;
Node * node2 = h->next->next;
node1->next = node2->next;
h->next = node2;
node2->next = node1;
}
h = h->next->next;
}
// 打印输出
h = head->next;
while (h) {
cout << h->val;
if (h->next != nullptr) cout << " ";
h = h->next;
}
}
};
int main() {
Solution::run();
}