腾讯音乐笔试20230413
T1
开始认为是一个dp问题,最后变成了求通项公式。。
通项公式为:
通过快速幂求解即可,注意类型为long long
:
#define MOD 1000000007
typedef long long ll;
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @return int整型
*/
ll fastpow(ll n, ll val){
if(n == 1) return val;
if(n == 0) return 1;
ll x = fastpow(n/2, val);
return n % 2 ? ((x*x) % MOD*val) % MOD : (x*x) % MOD;
}
int fun(int n) {
return (ll)((n-1)*fastpow(n+1, 2)) % MOD;
}
};
T2
类似树形dp的一个问题,直接在原树上进行修改了。
问题分析:每个新节点上的值是以该结点为子树根节点时,这棵树所有节点值的乘积结果的末尾0数量。
而末尾0的数量实际上由这个乘积值中因子2和因子5的数量最小值决定。
因此我们可以通过一个后序遍历,计算得到分别以左、右孩子为根的子树中因子2和5的数量,并加上当前节点值的因子2和5的数量,从而计算得到该结点的最终答案。
代码如下:
class Solution {
public:
TreeNode* valueOfTree(TreeNode* root) {
// write code here
dfs(root);
return root;
}
pair<int,int> dfs(TreeNode* node){
if(node == nullptr){
return {0, 0};
}
auto l = dfs(node->left);
auto r = dfs(node->right);
auto cur = cal(node->val);
auto n2 = cur.first + l.first + r.first;
auto n5 = cur.second + l.second + r.second;
node->val = min(n2, n5);
return {n2, n5};
}
//末尾0的数量与因子2和5的数量有关系
pair<int,int> cal(int num){
int n2 = 0, n5 = 0;
while(num%2 == 0){
num /= 2;
n2 += 1;
}
while(num%5 == 0){
num /= 5;
n5 += 1;
}
return {n2,n5};
}
};
T3
简单构造即可
后来想到更简单的构造如下序列:
class Solution {
public:
vector<int> fun(int n) {
// write code here
int len = n*(n+1) / 2;
vector<int> ans(len, 0);
ans[0] = n;
int start = 1;
int j = 1;
for(int i=1; i<len; i++){
ans[i] = j++;
if(j > n){
start += 1;
j = start;
}
}
return ans;
}
};
#我的实习求职记录##在找工作求抱抱#