題型
- 編程 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一部分(留下了羞愧的淚水)。