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;
}