【腾讯0326】春招实习笔试练习

1. 层序遍历二叉树

小红拿到一棵满二叉树,她通过层序遍历的顺序把每个节点的权值都告诉了你,保证每个节点的权值都不相同。
现在小红有q次询问,每次询问一个权值,小红想知道:
1. 这个节点是否存在?
2. 这个节点的左儿子和右儿子的权值是多少

输入描述:

第一行输入一个正整数n,代表二叉树的层数。
第二行输入2^n-1个正整数ai,代表这个完全二叉树的层序遍历。
第三行输入一个正整数q,代表询问次数
接下来q行,每一行输入一个x,代表一次询问
1<=n<=20, 1<=q<=10^5, 1<=x<=10^9, 1<=ai<=10^9

输出描述:

1. 如果存在权值为x的节点,则先输出一个字符串“Yes”。若该节点为叶子节点,则下一行输出一个字符串“LEAF”。若该节点不是叶子节点,则下一行输出两个正整数,分别代表该节点的左儿子和右儿子的权值。
2. 如果不存在权值为x的节点,则直接输出一个字符串“No”

示例1

输入

2
1 2 3
3 
1
3
5

输出

Yes
2 3
Yes
LEAF
No

思路:打卡题

#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <vector>
using namespace std;

int main() {
	int n; cin >> n;
	int maxN = pow(2, n) - 1;
	vector<int> trees(maxN + 5);
	unordered_map<int, int> hash_map;
	for (int i = 1; i <= maxN; i++) {
		cin >> trees[i];
		hash_map[trees[i]] = i;
	}
	int q; cin >> q;
	for (int i = 0; i < q; i++) {
		int temp = 0; cin >> temp;
		if (hash_map[temp] == 0) {
			cout << "No" << endl;
		}
		else {
			cout << "Yes" << endl;
			int root = hash_map[temp];
			if (root * 2 > maxN) {
				cout << "LEAF" << endl;
			}
			else {
				cout << trees[root * 2] << ' ' << trees[root * 2 + 1] << endl;
			}
		}
	}
}

2. 折叠回文串

题目描述:

给出一个长度为n的字符串s,你可以进行折叠字符串的回文子串操作任意次(可以0次):
如abba折叠后可以为ab或ba;baaab折叠后可以为baa或aab。通过执行上述操作可以得到多少种不同的字符串?

输入描述:

第一行输入一个整数n(1<=n<=18)
第二行一个长度为n的字符串s,字符串仅包含小写字母

输出描述:

输出一个整数表示答案

示例1

输入

3
aba

输出

3

示例2

输入

5
aabaa

输出

8

思路:数据规模不大,遍历即可

#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
using namespace std;

string toStr(string s, int x, int y) {
	string temp;

	return temp;
}

int main() {
	int n; cin >> n;
	string s; cin >> s;
	unordered_map<string, int> hash_map;
	queue<string> q;
	q.push(s);
	while (!q.empty()) {
		string temp = q.front();
		for (int i = 0; i < temp.size(); i++) {
			int left = i, right = i + 1;
			while (left >= 0 && right < temp.size() && temp[left] == temp[right]) {
				string addS = temp.substr(0, i + 1) + temp.substr(right + 1);
				if (hash_map[addS] == 0) {
					hash_map[addS]++;
					q.push(addS);
				}
				left--; right++;
			}

			left = i - 1, right = i + 1;
			while (left >= 0 && right < temp.size() && temp[left] == temp[right]) {
				string addS1 = temp.substr(0, i + 1) + temp.substr(right + 1);
				string addS2 = temp.substr(0, left) + temp.substr(i);
				if (hash_map[addS1] == 0) {
					hash_map[addS1]++;
					q.push(addS1);
				}
				if (hash_map[addS2] == 0) {
					hash_map[addS2]++;
					q.push(addS2);
				}
				left--; right++;
			}
		}
		q.pop();
	}
	cout << hash_map.size() + 1;
	return 0;
}

3. 最小的权值排序数组

给定两个整数数组A,B,数组长度都为N,数组B为权值数组,权值数据范围为[0,2],请构造一个数组C,满足以下条件。
1. 长度为N
2. 数组元素范围为[1,N],且元素值不能重复,即为N的一个排列
3. 如果数组下标为i<j,且有B[i]>B[j],那么一定要保证C[i]>C[j]
4. 数组C与数组A每个元素之差的和的绝对值最小,x
请你输出这个x的最小值

输入描述:

第一行输入一个正整数N
第二行输入N个正整数,每个数代表数组A的元素
第三行输入N个整数,每个数代表数字B的元素,范围为[0,2]
1<=N<=10^5,1<=Ai<=10^9,1<=Bi<=2

输出描述:

输出x

示例1

输入

4
2 1 4 2
2 2 2 2

输出

1

思路:没测试过更多的用例,感觉应该问题不是特别大

#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
using namespace std;

bool cmp(vector<int> &a, vector<int> &b) {
	return a[0] < b[0];
}

int main() {
	int n; cin >> n;
	vector<int> a(n), b(n);
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	vector<vector<int>> zero, one, two;
	for (int i = 0; i < n; i++) {
		cin >> b[i];
		if (b[i] == 0) {
			zero.push_back({a[i], i});
		}
		else if (b[i] == 1) {
			one.push_back({ a[i], i });
		}
		else {
			two.push_back({ a[i], i });
		}
	}

	sort(zero.begin(), zero.end(), cmp);
	sort(one.begin(), one.end(), cmp);
	sort(two.begin(), two.end(), cmp);
	vector<int> c;
	int cnt = 1, res = 0;
	for (int i = 0; i < zero.size(); i++) {
		res += abs(cnt - zero[i][0]);
		cnt++;
	}
	for (int i = 0; i < one.size(); i++) {
		res += abs(cnt - one[i][0]);
		cnt++;
	}
	for (int i = 0; i < two.size(); i++) {
		res += abs(cnt - two[i][0]);
		cnt++;
	}
	cout << res << endl;
	return 0;
}

4. 车

在一个由n*m个格子组成的矩阵棋盘maze上,第i行第j列的格子编号为(i,j),maze的格子只可能是障碍或者道路,牛牛初始在(1,1)处,他每一步可以沿道路水平方向向右或者垂直方向向下移动若干格子,但是不能越过障碍,现在牛牛想知道他有多少种方案从(1,1)到达(n,m),由于答案可能会很大,因此你只需要输出答案对10^9+7取模的结果即可。

输入描述:

第一行输入两个正整数n,m代表棋盘的大小
接下来n行每行输入一个长度为m的字符串。若为“#”,则表示障碍物;为“.”则表示为道路
2<=n,m<=2000

输出描述:

输出一个数字表示方案数对10^9+7取模的结果

示例1

输入

2 3
...
#..

输出

3

示例2

输入

5 5
.....
#....
#....
.....
.....

输出

419

思路:之前笔试有做过这道题,只能过一半用例。dp思路,用快速幂计算累计和

#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
using namespace std;

int main(){
	int n, m;
	cin >> n >> m;
	vector<vector<char>> graph(n, vector<char>(m));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> graph[i][j];
		}
	}
	vector<vector<int>> dp(n, vector<int>(m));
	vector<vector<int>> dp_cols(n, vector<int>(m));
	vector<vector<int>> dp_rows(n, vector<int>(m));
	dp[0][0] = dp_cols[0][0] = dp_rows[0][0] = 1;

	for (int i = 1; i < m; i++) {
		if (graph[0][i] == '#')	break;
		dp[0][i] = dp_rows[0][i - 1];
		dp_rows[0][i] = dp_rows[0][i - 1] + dp[0][i];
		dp_cols[0][i] = dp[0][i];
	}

	for (int i = 1; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (graph[i][j] == '#')	continue;
			dp[i][j] = dp_cols[i - 1][j];
			if (j > 0) {
				dp[i][j] += dp_rows[i][j - 1];
				dp_rows[i][j] = dp_rows[i][j - 1] + dp[i][j];
			}
			dp_cols[i][j] = dp_cols[i - 1][j] + dp[i][j];
		}
	}
	cout << dp[n - 1][m - 1];

	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值