题型
- 编程 3道 120分钟
编程1:员工评选
投票选举最佳员工,选出得票数最高的员工,若:
1)票数相同,按名字的字典序排序;
2)票数相同且名字有包含关系(Tom和Tomy),则名字短者在前。
- 输入:一行,名字之间用
,
隔开,如:Tom,Lucy,Tom,Jack,Rose
; - 输出:最佳员工的名字,如:
Tom
; - 思路:设置结构体存储名字和票数,创建一个结构体数组,然后调用
sort
函数传一个lamda表达式进行排序,最后输出第一个元素; - 参考代码(AC 75%):
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<string>
#include<set>
using namespace std;
bool contain(string &s1, string &s2);
struct person{
string name;
int vote;
person(string s, int v):name(s),vote(v){}
};
int main(){
string str;
cin >> str;
vector<string> names;
map<string, int> votes;
int start = 0, end = 0;
while (end != str.size())
{
if (str[end] == ',')
{
string name = str.substr(start, end - start);
names.push_back(name);
start = end + 1;
end++;
}
else if (isalpha(str[end]))
end++;
else
{
cout << "error.0001";
return 0;
}
}
names.push_back(str.substr(start, end - start));
for (auto &n : names)
votes[n]++;
vector<person> ps;
for (auto v : votes)
ps.push_back(person(v.first, v.second));
sort(ps.begin(), ps.end(),
[&votes](const person &p1, const person &p2){
if (p1.vote != p2.vote)
return p1.vote > p2.vote;
else if (contain(p1.name, p2.name))
return p1.name.size() < p2.name.size();
else
return p1.name < p2.name ;
}
);
cout << ps[0].name;
return 0;
}
bool contain(string &s1, string &s2)
{
if (s1.size() < s2.size())
{
string temp = s2;
s2 = s1;
s1 = temp;
}
for (int i = 0; i<=s1.size() - s2.size(); i++)
{
if (s1[i] == s2[0])
{
bool tag = true;
int j = 0;
while(j < s2.size())
{
if(s1[i + j] != s2[j])
{
tag = false;
break;
}
j++;
}
if(tag) return true;
}
}
return false;
}
编程2:字符匹配
这道题题意看的不是很懂。
给出一个待匹配串,一个表示若干寄存器的固定格式的母串,寄存器格式:xxx[name:xxx,mask:xxx,val:xxx]
,母串有多个寄存器字符串通过,
相连,匹配规则:1)待匹配串和寄存器编号相同;2)待匹配串的name、mask、val和母串中的某个寄存器相同。
- 输入:待匹配串,母串,空格相隔;
- 输出:对于每一个匹配到的寄存器,输出寄存器的
name mask val
空格相隔; - 思路:这道题最后没时间了(代码里有大量的if/else没来得及优化),就只考虑了待匹配串是一个寄存器编号的情况。设置下标start和end遍历母串,不断截取需要的字符串进行比较或者输出就行。
- 参考代码(AC 75%):
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main(){
string str, sta;
cin >> str >> sta;
string temp;
int start = 0, end = 0;
while (end != sta.size())
{
if (sta[end] == '[')
{
string s = sta.substr(start, end - start);
start = end + 1;
end++;
if (str == s)
{
while (sta[end] != ']')
{
if (sta[end] == '=')
{
start = end + 1;
end++;
}
else if (sta[end] == ',')
{
string s = sta.substr(start, end - start);
cout << s << " ";
start = end + 1;
end++;
}
else
end++;
}
string s = sta.substr(start, end - start);
cout << s << " ";
cout << endl;
}
}
else if (sta[end] == ',')
{
start = end + 1;
end++;
}
else
end++;
}
return 0;
}
编程3:最长调用链
给出n个函数,每个函数的权值,以及每个函数可以调用的其他函数,输出权值最大的调用链的权值。
- 输入:第一行,
x a b c d ...
x代表函数的个数,后边的x个数代表每个函数可以调用的其他函数个数;
接下来x行,每行如z y a b c ...
z代表函数编号,y代表函数权值,后面的若干数代表函数x可以调用的函数编号; - 输出:最大权值;
- 思路:记忆递归,但是提示
段错误:可能数组越界或者递归深度过大
,之前没记忆化的时候也是这个提示,而且AC率没有变; - 参考代码(AC 60%):
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
int maxval = 0;
map<int, int> cache;
int calcu(vector<vector<int>> &call, set<int> &memo, int index, vector<int> &val, int curr);
int main(){
int n;
cin >> n;
vector<int> temp(n + 1);
for (int i = 1; i <= n; i++)
cin >> temp[i];
vector<vector<int>> call(n + 1);
vector<int> val(n + 1);
for (int i = 1; i <= n; i++)
{
int x, v;
cin >> x >> v;
val[x] = v;
for (int j = 0; j<temp[i]; j++)
{
int x;
cin >> x;
call[i].push_back(x);
}
}
for (int i = 1; i <= n; i++)
{
if (temp[i] != 0)
{
set<int> memo;
if (calcu(call, memo, i, val, 0) == -1)
{
cout << "R";
return 0;
}
}
}
cout << maxval;
return 0;
}
int calcu(vector<vector<int>> &call, set<int> &memo, int index, vector<int> &val, int curr)
{
if (memo.count(index))
{
return -1;
}
if (cache.count(index))
{
curr += cache[index];
maxval = max(maxval, curr);
return curr;
}
curr += val[index];
memo.insert(index);
if (call[index].size() == 0)
{
maxval = max(maxval, curr);
return curr;
}
for (auto v : call[index])
{
int temp = calcu(call, memo, v, val, curr);
if (temp == -1)
return -1;
cache[index] = max(cache[index], temp - curr);
memo.erase(v);
}
//no use
return curr;
}
华为的笔试题还是有一定难度的,而且输入的处理真的很让人脑阔疼,感觉自己一直在截字符串233,不过总的来说逻辑清晰的话还是能AC一部分(留下了羞愧的泪水)。