目录
题目来源复旦考研群群友分享~
题目1
题目描述:给定一颗二叉树,树的每个节点的值为一个正整数。如果从根节点到节点 N 的路径上不存在比节点 N 的值大的节点,那么节点 N 被认为是树上的关键节点。求树上所有的关键节点的个数
例子
:
输入:3, 1, 4, 3, null, 1, 5
输出:4
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
const int N = 10010;
int tree[N],idx=1;//树的下标从1开始存,i号结点的父节点为i/2
int main()
{
//处理输入数据
string str_line;
getline(cin, str_line);
stringstream ss(str_line);
string str_tmp;
while (getline(ss, str_tmp, ','))
{
if (str_tmp == "null")
{
idx++;
continue;
}
else
tree[idx++] = stoi(str_tmp);
}
int cnt = 0;
for (int i = 1; i <= idx; i++)
{
//空结点
if (tree[i] == 0)
continue;
bool isKeyNode = true;
//从父节点开始顺着路径遍历至根节点
//当前结点编号是i,则父节点编号为i/2
for (int j = i / 2; j > 0; j = j / 2)
if (tree[j] > tree[i])
{
isKeyNode = false;
break;
}
if (isKeyNode)
cnt++;
}
cout<< cnt<<endl;
return 0;
}
题目2
题目描述:训练场上有一个台阶,总共有 n 级。一个运动员可以跳 1 级,也可以跳 2 级。求运动员有多少种跳法。
解题思路:动态规划。f[ i ]表示到达第 i 级台阶的最多种跳法。对于第 i 级台阶,它可以是有 i-2 级台阶跳2级达到的,也可以是有 i - 1 级台阶跳1级到达的,所以状态转移方程为:
f[i]=f[i-1]+f[i-2]
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int f[N];
int main()
{
int n;
cin >> n;
//初始化第0级,1级的跳法
f[0] = 1, f[1] = 1; f[2] = 2;
for (int i = 2; i <= n; i++)
f[i] = f[i - 1] + f[i - 2];
cout<<f[n]<<endl;
//采用滚动数组进行优化
int a = 1, b = 1,cur=0;
for (int i = 2; i < n; i++)
{
cur = a + b;
a = b;
b = cur;
}
cout << cur << endl;
return 0;
}
题目3
题目描述:给定一个非负整数序列x1,x2,x3...,xn,可以给每一个整数取负数或者取原值,求有多少种取法使得这些整数的和等于期望值E 。
例子:
输入:1, 1, 1, 1, 1, 3
输出:5
样例解释:
-1+1+1+1+1 = 3
1-1+1+1+1 = 3
1+1-1+1+1 = 3
1+1+1-1+1 = 3
1+1+1+1-1 = 3
解题思路:动态规划。f[i][j] 表示 对于序列的前 i 个数,取得期望值 j 的方法的总数。
由于当前这个数可以取正取负,所以当取负值时,说明前i-1个数取得期望值 j+a[i] 的方法的总数;同理,当取正值时,说明前i-1个数取得期望值 j-a[i] 的方法的总数;所以状态转移方程为:
f[i][j]=f[i-1][j+a[i]]+f[i-1][j-a[i]]
感觉写起来有些边边角角的问题,代码待补充~