题目一
测试链接:LCR 132. 砍竹子 II - 力扣(LeetCode)
分析:对于特殊情况2和3直接返回1和2。观察到大于等于4时,如果长度模3等于0,则答案全部是由3相乘;如果长度模3等于1,则答案最后会有两个2相乘;如果长度模3等于2,则答案最后会有一个2相乘。且长度模3等于0时,3的个数是长度除以3;长度模3等于1时,3的个数是长度除以3-1;长度模3等于2时,3的个数是长度除以3。然后相乘即可得到答案。代码如下。
class Solution {
public:
int MOD = 1000000007;
int power(int number, int num){
int ans = 1;
int temp = number;
for(int i = 0;i < 32;++i){
if((num & (1 << i)) != 0){
ans = (int)(((long long)ans * temp) % MOD);
}
temp = (int)(((long long)temp * temp) % MOD);
}
return ans;
}
int cuttingBamboo(int bamboo_len) {
if(bamboo_len == 2){
return 1;
}
if(bamboo_len == 3){
return 2;
}
int tail = bamboo_len % 3 == 0 ? 1 : (bamboo_len % 3 == 1 ? 4 : 2);
int num = tail == 1 ? bamboo_len / 3 : (tail == 4 ? bamboo_len / 3 - 1 : bamboo_len / 3);
return (int)(((long long)power(3, num) * tail) % MOD);
}
};
题目二
分成k份的最大乘积
一个数字n一定要分成k份,得到的乘积尽量大是多少。数字n和k,可能非常大,到达10^12规模。结果可能更大,所以返回结果对1000000007取模。
来自真实大厂笔试,没有在线测试。
分析:乘积尽量大即k份尽可能相等,所以先将n除以k得到每一份的基础值,然后得到n模k的值即有多少基础值再加上1,相乘即可得到答案。代码如下。
class Solution {
public:
int MOD = 1000000007;
long long power(long long number, long long num){
long long ans = 1;
long long temp = number;
for(int i = 0;i < 64;++i){
if((num & (1 << i)) != 0){
ans = (ans * temp) % MOD;
}
temp = (temp * temp) % MOD;
}
return ans;
}
int maxValue(long long n, long long k) {
long long a = n / k;
long long b = n % k;
return (int)((power(a, k-b) * power(a+1, b)) % MOD);
}
};
题目三
会议必须独占时间段的最大会议数量
给定若干会议的开始、结束时间。你参加某个会议的期间,不能参加其他会议。返回你能参加的最大会议数量。
来自真实大厂笔试,没有在线测试。
分析:以会议的结束时间从小到大进行排序,对于当前时间如果小于等于当前会议的开始时间则代表可以参加,时间更新为当前会议的结束时间,遍历所有会议即可得到答案。代码如下。
class Solution {
public:
int maxMeetingNum(vector<vector<int>>& meeting){
int ans = 0;
int length = meeting.size();
sort(meeting.begin(), meeting.end(), [](vector<int>& v1, vector<int>& v2){
return v1[1] < v2[1];
});
int cur = -1;
for(int i = 0;i < length;++i){
if(cur <= meeting[i][0]){
++ans;
cur = meeting[i][1];
}
}
return ans;
}
};
题目四
测试链接:1353. 最多可以参加的会议数目 - 力扣(LeetCode)
分析:首先按照开始时间进行排序,然后用一个小根堆维护结束时间,遍历会议的时候,对于当前时间可以解锁的会议的结束时间进入小根堆,选择可以解锁的会议中结束时间最小的会议进行参加。遍历所有天数即可得到答案。代码如下。
class Solution {
public:
int maxEvents(vector<vector<int>>& events) {
int length = events.size();
sort(events.begin(), events.end(), [](vector<int>& v1, vector<int>& v2){
return v1[0] < v2[0];
});
auto cmp = [](int& a, int& b){
return a > b;
};
priority_queue<int, vector<int>, decltype(cmp)> p(cmp);
int ans = 0;
int index = 0;
for(int day = 1;day <= 100000;++day){
while (!p.empty() && day > p.top())
{
p.pop();
}
while (index < length && day >= events[index][0] && day <= events[index][1])
{
p.push(events[index][1]);
++index;
}
if(!p.empty()){
++ans;
p.pop();
}
}
return ans;
}
};
题目五
分析:对最小资本从小到大进行排序,用一个大根堆维护纯利润。遍历每一次选择项目的机会,对于当前资本可以解锁的项目的纯利润进入大根堆,选择当前纯利润最大的项目进行投资,将纯利润加入当前资本进行下一次的选择。遍历完即可得到答案。代码如下。
class Solution {
public:
struct project
{
int profit;
int capital;
};
int findMaximizedCapital(int k, int w, vector<int>& profits, vector<int>& capital) {
int length = profits.size();
vector<project> pro;
pro.reserve(length);
for(int i = 0;i < length;++i){
project temp;
temp.profit = profits[i];
temp.capital = capital[i];
pro.push_back(temp);
}
sort(pro.begin(), pro.end(), [](project& p1, project& p2){
return p1.capital < p2.capital;
});
auto cmp = [](int& a, int& b){
return a < b;
};
priority_queue<int, vector<int>, decltype(cmp)> p(cmp);
for(int i = 0, index = 0;i < k;++i){
while (index < length && pro[index].capital <= w)
{
p.push(pro[index].profit);
++index;
}
if(!p.empty()){
w += p.top();
p.pop();
}
}
return w;
}
};
题目六
加入差值绝对值直到长度固定
给定一个非负数组arr,计算任何两个数差值的绝对值。如果arr中没有,都要加入到arr里,但是只加一份。然后新的arr,继续计算任何两个数差值的绝对值,如果arr中没有,都要加入到arr里,但是只加一份。一直到arr大小固定,返回arr最终的长度。
来自真实大厂笔试,没有在线测试。
分析:观察可得这个数组中的所有数字是原数组除0之外所有数的最大公约数到原数组中的最大值,每一个数都是最大公约数的倍数。所以思路是求得最大公约数,得到基础个数,然后加上词频统计中个数不为1的数的剩余个数。对于是否有0的情况,如果原数组中有0,则加上原数组中0的个数;如果原数组中没0则取决于最大词频数,如果最大词频数不超过1,则没有零,超过1则加上一个0。代码如下。
class Solution {
public:
int get_gcd(int a, int b){
return b == 0 ? a : get_gcd(b, a % b);
}
int getLen(vector<int> arr){
int gcd = 0;
int maxValue = 0;
int length = arr.size();
for(int i = 0;i < length;++i){
if(arr[i] != 0){
gcd = arr[i];
}
maxValue = max(maxValue, arr[i]);
}
if(gcd == 0){
return length;
}
map<int, int> table;
map<int, int>::iterator pos;
int maxCnt = 1;
for(int i = 0;i < length;++i){
if(arr[i] != 0){
gcd = get_gcd(gcd, arr[i]);
}
pos = table.find(arr[i]);
if(pos != table.end()){
++((*pos).second);
maxCnt = max(maxCnt, (*pos).second);
}else{
table.insert(pair<int, int>(arr[i], 1));
}
}
int ans = maxValue / gcd;
for(int i = 0;i < length;++i){
if(arr[i] != 0){
pos = table.find(arr[i]);
ans += ((*pos).second - 1);
}
}
pos = table.find(0);
ans += (pos == table.end() ? (maxCnt > 1 ? 1 : 0) : (*pos).second);
return ans;
}
};