✨个人主页: 北 海
🎉所属专栏: C/C++相关题解
🎃操作环境: Visual Studio 2019 版本 16.11.17
文章目录
- 选择题
- 1.C基础语法
- 编程题
- 组队竞赛
- 删除公共字符
选择题
1.C基础语法
题目:以下程序的运行结果是()
#include <stdio.h>
int main(void)
{
printf("%s , %5.3s\n", "computer", "computer");
return 0;
}
选项:
A. computer , puter
B. computer , com
C. computer , computer
D. computer , compu.ter
分析:本题知识点为 printf
打印格式控制,其中 %s
为打印字符串,而数字可以控制格式长度:其中 .
前的数字表示打印时缩进 N
个空格,而 .
后的数字表示取目标前 M
位字符
关于其他输出格式
第一个 %s
在打印时,表示直接将 computer
打印完,而第二个 %s
表示先缩进 5
个空格,在取 computer
的前 3
个字符打印,剩余字符不再打印
注意: 当 .
后面的数字大于目标字符串长度时,直接打印整个字符串
结果:
B
编程题
组队竞赛
题目链接:组队竞赛
题目分析:输入 N
组队伍信息(一个队伍固定为 3
人),规定队伍中的第二名队员(第二大的值)的水平为该队的水平值,尽可能将队员进行合理组队,确保总的队伍水平值为最大
- 如何确保平均水平值为最大?在组队时,将当前队员中的
最高
、次高
和最低
组成一个队,直到所有的队员都被选中,此时问题就很简单了,关键点在于 排序 - 输入的数据可能为乱序,因此需要先排序,方便进行队员选取
- 假设当前队员还剩余
N
个,那么此时只需要将max += N - 1
,取得当前队伍的水平值,再N -= 2
,将已经匹配完的队员数去掉,如此重复,直到所有队员都被选中
代码
时间复杂度:3n + (3n)*log(3n) + n
->O(N*logN)
空间复杂度:O(3n)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n = 0;
while (cin >> n)
{
vector<int> member(n * 3); //成员池
for (int i = 0; i < n * 3; i++)
cin >> member[i]; //读取成员值
sort(member.begin(), member.end()); //排序
int pos = 0;
int N = member.size() - 1;
long long max = 0; //注意:存在溢出的情况
while (pos < N)
{
max += member[N - 1];
pos++;
N -= 2;
}
cout << max << endl;
}
return 0;
}
注意:
- 输入的
n
为队伍数,实际队员数为3 * n
- 获取队员水平后,需要对数值进行排序,否则无法进行后续计算
- 存在溢出问题,因此
max
需要一个更大的类型
结果
删除公共字符
题目链接:删除公共字符
题目分析:将 字符串1
中所有在 字符串2
中出现的字符删除,本质:删除公共字符
- 思路1:先
字符串2
遍历,然后将遍历得到的值,带到字符串1
中再去遍历,如果发现相同的,就删除 - 思路2:重构字符串,将
字符串2
构建为map
,对字符串1
进行遍历,如果该字符已出现在map
中,那么就不参与重构
两种思路各有优劣,思路1耗时间(重复遍历+删除),而思路2耗费空间,并且是间接到达删除的要求
思路1
#include <iostream>
#include <string>
using namespace std;
//思路1
int main()
{
string str1, str2;
//需要使用 getline 因为输入字符串有空格
getline(cin, str1);
getline(cin, str2);
//先将 str2 遍历一遍
for (auto e : str2)
{
int val = e;
auto it = str1.begin();
//再将 str1 遍历,将需要删除的字符移除
while (it != str1.end())
{
//注意迭代器失效问题
if (*it == val)
it = str1.erase(it); //删除字符
else
it++;
}
}
cout << str1 << endl;
return 0;
}
思路2
#include <iostream>
#include <string>
#include <map>
using namespace std;
//思路2
int main()
{
string str1, str2;
//需要使用 getline 因为输入字符串有空格
getline(cin, str1);
getline(cin, str2);
//建立 map 表,表示是否出现
map<char, int> table;
for (auto e : str2) table.insert(make_pair(e, 1));
//将 str1 遍历,重构字符串
string tmp;
for (auto e : str1)
{
if (table.find(e) == table.end())
tmp += e; //只有未出现的,才能记录
}
str1 = tmp;
cout << str1 << endl;
return 0;
}
注意: 字符串1
中包含空格,需要使用 getline
函数读取
上述几题都比较简单,其中
组队竞赛
需要想清楚利益最大化原则,配合排序这个关键思想,就能快速突破问题
相关文章推荐
C++题解 | 逆波兰表达式相关
C语言题解 | 去重数组&&合并数组
C语言题解 | 消失的数字&轮转数组