2020/4/22 华为暑期实习笔试三道编程题
楼主ac前两道题,最后一道题自己注意力不是很集中,没做完。。。笔试结束后用回溯法+暴力解法写完了,但是发现一些小问题过不了测试用例,也就不再折腾了,希望评论区能有大佬朋友给出第三题的答案和思路
---------------------------------------------------------------------------
第一题比较简单
#include<queue>
#include<vector>
#include<iostream>
#include<stdio.h>
#include<numeric>
#include<algorithm>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<functional>
#include<iterator>
#include<sstream>
#include<string>
#include <math.h>
#include<stdlib.h>
using namespace std;
int main() {
string s;
getline(cin, s);
string tmp;
for (auto& ch : s) {
if (ch >= '0' && ch <= '9') {
tmp += ch;
}
}
sort(tmp.begin(), tmp.end());
cout << tmp << endl;
return 0;
} ---------------------------------------------------------------------------
第二题题目很繁琐,但其实并不难,只需要按图上的流程,反过来检验一遍就行了
1.找出各个分段
2.处理每一个分段的转义字符
3.检验每一个分段的长度
4.输出结果
int main() {
string s;
getline(cin, s);
stringstream ss(s);
vector<string> vec;
string tool;
while (ss >> tool) {
vec.push_back(tool);
}
// 1.找分段
vector<vector<string> > allPart;
for (auto iter = vec.begin(); iter != vec.end();) {
if (*iter == "5a") {
while (iter != vec.end() && *iter == "5a") { ++iter; }
}
if (iter != vec.end()) {
vector<string> aPart;
while (iter != vec.end() && *iter != "5a") {
aPart.push_back(*iter);
++iter;
}
allPart.push_back(aPart);
}
}
// 2.处理每一分段的转义字符
for (auto pIter = allPart.begin(); pIter != allPart.end();) {
bool isBadPart = false;
for (auto iter = (*pIter).begin(); iter < (*pIter).end()-1;) {
if (*iter == "5b" && (*(iter+1) == "bb" || *(iter + 1) == "ba")) {
// 5b
if (*iter == "5b" && *(iter + 1) == "bb") {
iter = (*pIter).erase(iter + 1);
}
// 5a
else if (*iter == "5b" && *(iter + 1) == "ba") {
*iter = "5a";
iter = (*pIter).erase(iter + 1);
}
}
else if (*iter == "5b" && (*(iter + 1) != "bb" && *(iter + 1) != "ba")) {
isBadPart = true;
break;
}
else {
++iter;
}
}
if (isBadPart == true) {
pIter = allPart.erase(pIter);
continue;
}
++pIter;
}
// 3.检验长度
for (auto pIter = allPart.begin(); pIter != allPart.end();) {
string lenStr = (*pIter).back();
int len = strtoll(lenStr.c_str(), NULL, 16);
if (len != (*pIter).size()-1) {
pIter = allPart.erase(pIter);
}
else {
++pIter;
}
}
// 输出正确报文
for (auto &eachPart : allPart) {
cout << "5a ";
for (auto &e : eachPart) {
if (e == "5a") {
cout << "5b ba ";
}
else if (e == "5b") {
cout << "5b bb ";
}
else {
cout << e << ' ';
}
}
}
cout << "5a " << endl;
return 0;
} ---------------------------------------------------------------------------
第三题,我觉得是有点难度的,目前还没做出来,下面是我的实现,暂未通过用例
思路是
1.先用回溯法(DFS)找出所有划分的方案
2.根据每一种划分方案找到其对应的最小分段值 3.找出最大的最小分段值,把对应的划分方案加上符号'/'打印出去
void DFS(vector<vector<int> >& allDivide, vector<int> tmp, int start, int limit, int m) {
if (tmp.size() == limit) {
allDivide.push_back(tmp);
return;
}
for (int i = start; i < m; ++i) {
tmp.push_back(i);
DFS(allDivide, tmp, i + 1, limit, m);
tmp.pop_back();
}
}
int main() {
int m, k;
cin >> m >> k;
vector<int> arr(m);
int tmp;
for (int i = 0; i < arr.size(); ++i) {
cin >> tmp;
arr[i] = tmp;
}
vector<vector<int> > allDivide;
vector<int> temp;
DFS(allDivide, temp, 1, k - 1, m);
vector<int> minValues;
for (auto ÷ : allDivide) {
vector<int> values;
values.push_back(accumulate(arr.begin(), arr.begin() + divide.front(), 0));
for (int i = 1; i < divide.size()-1; ++i) {
values.push_back(accumulate(arr.begin()+divide[i], arr.begin() + divide[i+1], 0));
}
values.push_back(accumulate(arr.begin() + divide.back(), arr.end(), 0));
minValues.push_back(*min_element(values.begin(), values.end()));
}
int maxIndex = 0;
for (int i = 1; i < minValues.size(); ++i) {
if (minValues[i] > minValues[maxIndex]) {
maxIndex = i;
}
}
// 输出
vector<int> ans = allDivide[maxIndex];
cout << minValues[maxIndex] << endl;
output(ans);
cout << "---" << endl;
int countCout = 0, countIndex = 0;
for (int i = 0; i < arr.size(); ++i) {
cout << arr[i] << ' ';
++countCout;
if (countIndex < ans.size() && countCout == ans[countIndex]) {
cout << "/ ";
++countIndex;
}
}
system("pause");
return 0;
} 欢迎交流!!!!

