华为机试真题练习汇总(71~80)
华为机试真题练习汇总(71~80)
题目来源:华为机试 - 牛客
标记 * 号的代表有难度的题目。
HJ71 字符串通配符
描述
问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
*:匹配0个或以上的字符(注:能被*和?匹配的字符仅由英文字母和数字0到9组成,下同)
?:匹配1个字符
注意:匹配时不区分大小写。
输入:
通配符表达式;
一组字符串。
输出:
返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false
代码:
#include <cctype>
#include <iostream>
#include <vector>
using namespace std;
bool judge (char& c) {
return (isalpha(c) || isalnum(c) || c == '.');
}
bool match(string p, string s) {
int plen = p.size();
int slen = s.size();
// dp[i,j]: p[0,...,i]与s[0,...,j]是否匹配
vector<vector<bool>> dp(plen + 1, vector<bool>(slen + 1, false));
// 初始化
dp[0][0] = true;
// 状态转移
for (int i = 1; i <= plen; i++) {
dp[i][0] = dp[i - 1][0] && (p[i - 1] == '*'); // 首字符为'*'的情况
for (int j = 1; j <= slen; j++) {
if (p[i - 1] == '*') {
dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
} else {
if (tolower(p[i - 1]) == tolower(s[j - 1])) // 要么两字符相等
dp[i][j] = dp[i - 1][j - 1];
if (p[i - 1] == '?' && judge(s[j - 1])) // 要么?通配
dp[i][j] = dp[i - 1][j - 1];
}
}
}
return dp[plen][slen];
}
int main() {
string p, s;
cin >> p >> s;
if (match(p, s)) {
cout << "true" << endl;
} else {
cout << "false" << endl;
}
return 0;
}
// 64 位输出请用 printf("%lld")
HJ72 百钱买百鸡问题
描述
公元五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
现要求你打印出所有花一百元买一百只鸡的方式。
输入描述:
输入任何一个整数,即可运行程序。
输出描述:
输出有数行,每行三个整数,分别代表鸡翁,母鸡,鸡雏的数量
代码:
#include <iostream>
using namespace std;
int main() {
int x;
cin >> x;
for (int i = 0; i <= 20; i++)
for (int j = 0; j <= 25; j++)
for (int k = 0; k <= 100; k++) {
if (i + j + k == 100 && 5 * i + 3 * j + k / 3.0 == 100.0)
cout << i << " " << j << " " << k << endl;
}
return 0;
}
// 64 位输出请用 printf("%lld")
HJ73 计算日期到天数转换
描述
根据输入的日期,计算是这一年的第几天。
保证年份为4位数且日期合法。
输入描述:
输入一行,每行空格分割,分别是年,月,日
输出描述:
输出是这一年的第几天
代码:
#include <iostream>
#include <vector>
using namespace std;
int isLeapYear(int y) {
return (y % 400 == 0) || (y % 100 != 0 && y % 4 == 0);
}
int trans(int y, int m, int d) {
const vector<int> days = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
int sum = 0;
for (int i = 0; i < m - 1; i++)
sum += days[i];
sum += d;
if (isLeapYear(y) && m > 2)
sum++;
return sum;
}
int main() {
int year, month, day;
cin >> year >> month >> day;
cout << trans(year, month, day) << endl;
return 0;
}
// 64 位输出请用 printf("%lld")
HJ74 参数解析
描述
在命令行输入如下命令:
xcopy /s c:\ d:\e,
各个参数如下:
参数1:命令字xcopy
参数2:字符串/s
参数3:字符串c:\
参数4: 字符串d:\e
请编写一个参数解析程序,实现将命令行各个参数解析出来。
解析规则:
1.参数分隔符为空格
2.对于用""包含起来的参数,如果中间有空格,不能解析为多个参数。比如在命令行输入xcopy /s “C:\program files” "d:“时,参数仍然是4个,第3个参数应该是字符串C:\program files,而不是C:\program,注意输出参数时,需要将”"去掉,引号不存在嵌套情况。
3.参数不定长
4.输入由用例保证,不会出现不符合要求的输入
输入描述:
输入一行字符串,可以有空格
输出描述:
输出参数个数,分解后的参数,每个参数都独占一行
代码:
#include <iostream>
#include <vector>
using namespace std;
int main() {
string input;
getline(cin, input);
vector<string> parameters;
string parameter = "";
bool flag = false; // 记录是否进入引号内
for (int i = 0; i < input.length(); i++) {
if (flag) { // 在引号内
if (input[i] != '\"')
parameter.push_back(input[i]);
else
flag = false;
} else { // 不在引号内
if (input[i] == ' ') {
// 遇到空格,截断
parameters.push_back(parameter);
parameter.clear();
} else if (input[i] == '\"') {
// 进入引号,设置flag
flag = true;
} else { // 其余添加进字符串
parameter.push_back(input[i]);
}
}
}
parameters.push_back(parameter);
cout << parameters.size() << endl;
for (string& p : parameters)
cout << p << endl;
return 0;
}
// 64 位输出请用 printf("%lld")
HJ75 公共子串计算
描述
给定两个只包含小写字母的字符串,计算两个字符串的最大公共子串的长度。
注:子串的定义指一个字符串删掉其部分前缀和后缀(也可以不删)后形成的字符串。
输入描述:
输入两个只包含小写字母的字符串
输出描述:
输出一个整数,代表最大公共子串的长度
代码:
#include <iostream>
#include <vector>
using namespace std;
int LCSLength(string& s1, string& s2) {
int M = s1.length(), N = s2.length();
vector<vector<int>> dp(M + 1, vector<int>(N + 1, 0));
int maxLen = 0;
for (int i = 1; i <= M; i++)
for (int j = 1; j <= N; j++) {
if (s1[i - 1] == s2[j - 1])
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = 0;
if (dp[i][j] > maxLen)
maxLen = dp[i][j];
}
return maxLen;
}
int main()
{
string s1, s2;
cin >> s1 >> s2;
cout << LCSLength(s1, s2) << endl;
return 0;
}
// 64 位输出请用 printf("%lld")
HJ76 尼科彻斯定理
描述
验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。
例如:
1^3=1
2^3=3+5
3^3=7+9+11
4^3=13+15+17+19
输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。
输入描述:
输入一个int整数
输出描述:
输出分解后的string
代码:
#include <iostream>
using namespace std;
int main() {
int m;
cin >> m;
int mid = m * m;
if (mid % 2 == 1) {
int begin = mid - m / 2 * 2;
int end = mid + m / 2 * 2;
for (int i = begin; i <= end; i += 2) {
if (i != end)
cout << i << "+";
else
cout << i << endl;
}
} else {
int begin = mid - 1 - (m / 2 - 1) * 2;
int end = mid + 1 + (m / 2 - 1) * 2;
for (int i = begin; i <= end; i += 2) {
if (i != end)
cout << i << "+";
else
cout << i << endl;
}
}
return 0;
}
// 64 位输出请用 printf("%lld")
* HJ77 火车进站
描述
给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号,火车站只有一个方向进出,同时停靠在火车站的列车中,只有后进站的出站了,先进站的才能出站。
要求输出所有火车出站的方案,以字典序排序输出。
输入描述:
第一行输入一个正整数N(0 < N <= 10),第二行包括N个正整数,范围为1到10。
输出描述:
输出以字典序从小到大排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample。
代码 1:
#include <functional>
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> trains(n);
for (int i = 0; i < n; i++)
cin >> trains[i];
vector<vector<int>> res;
vector<int> seq;
stack<int> s;
// 回溯算法
function<void(int)> dfs = [&](int index) {
if (index >= n && s.empty()) {
res.push_back(seq);
return;
}
// 进栈
if (index < n) {
s.push(trains[index]);
dfs(index + 1);
// 回溯
s.pop();
}
// 出栈
if (!s.empty()) {
seq.push_back(s.top());
s.pop();
dfs(index);
// 回溯
s.push(seq.back());
seq.pop_back();
}
};
dfs(0);
sort(res.begin(), res.end());
for (vector<int>& v : res) {
for (int& x : v)
cout << x << " ";
cout << endl;
}
return 0;
}
// 64 位输出请用 printf("%lld")
代码 2:
#include <algorithm>
#include <functional>
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> trains(n);
for (int i = 0; i < n; i++)
cin >> trains[i];
const vector<int> original_seq(trains);
// 全排列前要先排序
sort(trains.begin(), trains.end());
auto check = [&](vector<int>& arr) -> bool {
stack<int> s;
int idx = 0;
for (const int& train : original_seq) {
s.push(train);
while (!s.empty() && arr[idx] == s.top()) {
s.pop();
idx++;
}
}
return s.empty();
};
// 全排列
do {
if (check(trains)) {
for (int& x : trains)
cout << x << " ";
cout << endl;
}
} while (next_permutation(trains.begin(), trains.end()));
return 0;
}
// 64 位输出请用 printf("%lld")
HJ80 整型数组合并
描述
题目标题:
将两个整型数组按照升序合并,并且过滤掉重复数组元素。
输出时相邻两数之间没有空格。
输入描述:
输入说明,按下列顺序输入:
1 输入第一个数组的个数
2 输入第一个数组的数值
3 输入第二个数组的个数
4 输入第二个数组的数值
输出描述:
输出合并之后的数组
代码:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
vector<int> v;
cin >> n;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
v.push_back(x);
}
cin >> n;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
v.push_back(x);
}
sort(v.begin(), v.end());
// 分组循环
for (int i = 0; i < v.size(); i++) {
while (i <= v.size() - 1 && v[i] == v[i + 1])
i++;
cout << v[i];
}
return 0;
}
// 64 位输出请用 printf("%lld")