华为通用软件2019笔试

第一题

  • 用指针依次寻找数组内的数字,反复利用sum = sum * 10 + s[i] - '0'
  • 根据题意:
    • A i < = B j A_i<=B_j Ai<=Bj
    • A i A_i Ai找不到R范围内的 B j B_j Bj,则列出最近的 B j B_j Bj(仍满足条件1)
    • 仍找不到则丢弃 A i A_i Ai
  • 测试样例:A={11,13,15},B={12,14,16},R=1
  • 时间复杂度:
  • **空间复杂度:**开辟了两个vector, O ( n ) O(n) O(n)
int main(){
	string s;
	cin >> s;
	vector<int> A, B;
	int i = 0;
	// 读取A数组
	while (i < s.size() && s[i] != '{') i++;
	i++;
	int num = 0;
	while (i < s.size()) {
		if (s[i] == ',') {
			A.push_back(num);
			num = 0;
			i++;
		}
		else if (s[i] == '}') {
			A.push_back(num);
			num = 0;
			i++;
			break;
		}
		else{
			num = num * 10 + s[i] - '0';
			i++;
		}
	}

	// 读取B数组
	while (i < s.size() && s[i] != '{') i++;
	i++;
	num = 0;
	while (i < s.size()) {
		if (s[i] == ',') {
			B.push_back(num);
			num = 0;
			i++;
		}
		else if (s[i] == '}') {
			B.push_back(num);
			num = 0;
			i++;
			break;
		}
		else{
			num = num * 10 + s[i] - '0';
			i++;
		}
	}
	// 读取R
	int R = 0;
	while (i < s.size() && s[i] != '=') i++;
	i++;
	while (i < s.size()) {
		R += R * 10 + s[i] - '0';
		i++;
	}
    
	int a = 0, b = 0;
	while (a < A.size()) {
		b = 0;
		while (b < B.size() && B[b] < A[a]) b++;
		if (b < B.size() && B[b] - A[a] <= R)
			cout << '(' << A[a] << ',' << B[b] << ')';
		else if (b < B.size()) 
			cout << '(' << A[a] << ',' << B[b - 1] << ')';
		a++;
	}
	return 0;
}

第二题:反转单词

  • 1、翻转每个单词,然后在翻转整个字符;2、首尾多余空格、单词间多余空格剔除

  • 时间复杂度:整个字符串总共扫描两遍,所以时间复杂度是 O ( n ) O(n) O(n)

  • 空间复杂度:只使用 O ( 1 ) O(1) O(1)的额外空间

string reverseWord(string s)
{
	int k = 0; // 为了压缩多余空格,k:当前实际存的位置在终点的什么地方
	for (int i = 0; i < s.size();) {
		int j = i;
		while (j < s.size() && s[j] == ' ') j++;
		if (j == s.size()) break;
		i = j;
		while (j < s.size() && s[j] != ' ') j++;
		reverse(s.begin() + i, s.begin() + j);
		if (k) s[k++] = ' ';
		while (i < j) s[k++] = s[i++]; // 把第10行copy过来
	}
//单词间可能包含多余空格,翻转会将多余空格去掉,故每个单词可能向前移动,最后把多余的部分删掉
	s.erase(s.begin() + k, s.end());  // 删除k后面多余的部分
	reverse(s.begin(), s.end());
	return s;
}
int main()
{
		string s;
		getline(cin, s);
		string tmp;
		for (int i = 0; i < s.size(); i++) {
			if (s[i] == '-' && s[i + 1] == '-')
				s[i] = ' ', s[i + 1] = ' ';
			if (s[i] == ' ' && s[i + 1] == '-')
				s[i + 1] = ' ';
			if (s[i] == '-' && s[i + 1] == ' ')
				s[i] = ' ';
		}
		for (auto& c : s) {
			if (isalnum(c) || isspace(c) || c == '-')
				tmp.push_back(c);
		}
		string res = reverseWord(tmp);
		cout << res;	
	return 0;
}

第三题:航班号改签

  • 时间复杂度:
  • 空间复杂度:
N = input()
A = []
for i in range(0, int(N)):
    s = input()
    A.append(s)

M = input()
B = []
mp = {}
for i in range(0, int(M)):
    s = input()
    ss = s.split(',')
    mp[ss[0]+','+ss[1]] = ss[2] + ','+ss[3]
    B.append(s)

res = []
already = {} # 用来存储是否重复

for each in A:
    ss = each.split(',')
    news = ""
    if(mp.get(ss[0] + ',' + ss[1]) != None):
        news = mp.get(ss[0] + ',' + ss[1]) + ',' + ss[2]

    else:
        news = each
    findalready = news.split(',')
    if(already.get(findalready[0]+','+findalready[1]) == None): #去掉同航班,同座位号
        if(already.get(findalready[0]+','+findalready[2]) == None):# 去掉同用户,同航班
            res.append(news)
            already[findalready[0]+','+findalready[1]] = 1 # 把航班+座位号加入
            already[findalready[0]+','+findalready[2]] = 1 # 把航班+用户加入

for each in res:
    print(each)

你可能感兴趣的:(刷题)