力扣第252场周赛题解

声明:因为是先在注释里面写了思路,要看思路的话看注释吧。就不搬出来了
第一题、三除数
链接:https://leetcode-cn.com/problems/three-divisors/
思路:

​ 直接暴力循环,查找正除数的个数就可以了

代码实现:
class Solution {
public:
    bool isThree(int n) {
        int cur = 0 ;
        for(int i = 1 ; i <= n ; ++ i)
            cur += n % i == 0 ? 1 : 0 ;
        return cur == 3 ;
    }
};
第二题、你可以工作的最大周数
链接:https://leetcode-cn.com/problems/maximum-number-of-weeks-for-which-you-can-work/
思路:

​ 根据每周切换项目的规则,可以借助阶段任务最多的项目完成多次切换。推导结果看代码注释

代码实现:
class Solution {
public:
    long long numberOfWeeks(vector<int>& w) {
        sort(w.begin() , w.end()) ;
        long long sum = 0 , cur = 0 ;
        for(auto &i : w)
            sum += i ;  //计算所有数的总和
        cur = sum - w.back() ;  //计算除了最大的数,其他数的和
        if(cur < w.back())  //这是y + z + ... < x 的情况
            return cur * 2 + 1 ;
        return sum ;    //否则返回sum即可
    }
};

/*
x y z ....

x是最大的,判断是不是比其他的加起来都大

y + z + ... <= x 则最大结果为:(y + z) * 2 + 1
切换方法:一个x项目,一个其他项目,来回切换,最后可以再参与一次x项目

y + z + ... >= x 则最大结果为sum
切换方法,每个项目做一周,循环直到y + z + ... = x为止,然后一次其他项目,一次x项目来回切换直到所有项目完成
*/
第三题、收集足够苹果的最小花园
链接:https://leetcode-cn.com/problems/minimum-garden-perimeter-to-collect-enough-apples/
思路:

​ 使用二分的方法枚举边长即可,具体细节看代码注释

代码实现:
typedef long long ll ;
class Solution {
public:
    bool check(ll x , ll n){    //如果边长为x,苹果的总数>= n,返回ture,否则返回false
        ll y = (x + 1) * x / 2 ;
        ll tot = (2 * y + x * x) * (x + 1) * 2 ;
        if(tot >= n)
            return true ;
        return false ;
    }

    long long minimumPerimeter(long long n) {
        ll l = 0 , r = 1e6 + 10 ;
        while(l < r){
            ll mid = (l + r) / 2 ;
            if(check(mid , n))
                r = mid ;
            else
                l = mid + 1 ;
        }
        return l * 8 ;
    }
};

/*
设x为正方形的边到(0,0)的距离
x:

(0,0) 1 2 3 4 5 ... x
1     2 3 4 5 6 ....x+1
2     3 4 5 6 7 ... x+2
3                   x+3
4                   x+4
5  
.  
.  
.  
x     x+1 x+2 ....  x+x

第1列苹果总和: (x + 1) * x / 2
第2列苹果总和: (x + 1) * x / 2 + x
第3列苹果总和: (x + 1) * x / 2 + 2 * x
...
第x列苹果总和: (x + 1) * x / 2 + x * x

设:y = (x + 1) * x / 2 

那么y的负半轴上的苹果加上右下角的苹果的总和:tot = (y + y + x * x) * (x + 1) / 2 ;
那么整个土地的苹果总和为:ans = tot * 4

*/
第四题、统计特殊子序列的数目
链接:https://leetcode-cn.com/problems/count-number-of-special-subsequences/
思路:

​ 使用动态规划,推导出状态转移方程,具体看代码注释

代码实现:
const int N = 1e5 + 10 ;
const int mod = 1e9 + 7 ;
class Solution {
    int f[N][3] ;
    /*
    f[i][0] 表示0...0的子序列数
    f[i][1] 表示0..01..1的子序列数
    f[i][2] 表示0..01..12..2的子序列数
    */
public:
    int countSpecialSubsequences(vector<int>& nums) {
        int n = nums.size() ;
        for(int i = 1 ; i <= n ; ++ i){
            f[i][0] = f[i - 1][0] ;     //继承i - 1的
            f[i][1] = f[i - 1][1] ;
            f[i][2] = f[i - 1][2] ;
            if(nums[i - 1] == 0)
                f[i][0] = (f[i - 1][0] * 2 + 1) % mod ;
                /*
                如果当前数字为0,那么f[i][0]有三种来源:
                    第一、由f[i - 1][0]的情况不变得来,情况数为f[i - 1][0]
                    第二、由f[i - 1][0]的情况后面加上一个0得来,情况数为f[i - 1][0]
                    第三、仅由当前这个0组成的子序列,情况数为1
                */
            else if(nums[i - 1] == 1)
                f[i][1] = ((f[i - 1][1] * 2) % mod + f[i - 1][0]) % mod ;
                /*
                如果当前数字为1,那么f[i][1]的来源有三种:
                    第一、由f[i - 1][1]的情况不变得来,情况数为f[i - 1][1]
                    第二、由f[i - 1][1]的情况后面加上当前这个1得来,情况数为f[i - 1][1]
                    第三、由f[i - 1][0]的情况后面加上当前这个1得来,情况数为f[i - 1][0]
                */
            else
                f[i][2] = ((f[i - 1][2] * 2) % mod + f[i - 1][1]) % mod ;
                /*
                如果当前数字为2,那么f[i][1]的来源有三种:
                    第一、由f[i - 1][2]的情况不变得来,情况数为f[i - 1][2]
                    第二、由f[i - 1][2]的情况后面加上当前这个2得来,情况数为f[i - 1][2]
                    第三、由f[i - 1][1]的情况后面加上当前这个2得来,情况数为f[i - 1][1]
                */
        }
        return f[n][2] ;    //返回结果
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值