285周赛(未完待更)

总览

10点钟才起来,打的时候又饿又冷(降温了

T1写了25分钟,排名到了五千,那时的心跳已经有点儿沉闷了🤣。然后强制自己冷静下来,又A了两题。个人感觉后期发挥得还不错吧。这种被第一题卡的经历还是比较少的,hhhh。

各题详解

T1

首先又犯了题没看清就写的错误,这个错误已经犯了不止两次了,以后不能再毛躁。

我哪一点没有看明白呢?对于相邻下标 ij ,如果 nums[i] == nums[j] , 则认为这两下标属于 同一个 峰或谷。我一开始忽略了相邻下标、直接用set然后错大发了。

我的暴力解法思路是:

  1. 对于1 ~ n-2 下标:将他们标记为“谷底”或“峰”(双指针实现)
  2. 对所有的“谷底”和“峰”,筛去相邻的(双指针)
class Solution {
public:
    int countHillValley(vector<int>& nums) {
        int n = nums.size();
        vector<int> s1, s2; 
        for(int i = 1; i < n - 1; ++ i)
        {
            int j1 = i - 1, j2 = i + 1;
            while(j1 >= 0 && nums[j1] == nums[i]) j1 --; 
            while(j2 < n && nums[j2] == nums[i]) j2 ++; 
            if(j1 >= 0 && j2 < n && nums[j1] < nums[i] && nums[j2] < nums[i]) s1.push_back(i);
            if(j1 >= 0 && j2 < n && nums[j2] > nums[i] && nums[j1] > nums[i]) s2.push_back(i); 
        }
        
        int res = 0;
        n = s1.size();
        for(int i = 0; i < s1.size(); ++ i)
        {
            int j = i + 1;
            while(j < n && s1[j] == s1[j-1] + 1) j ++;
            res ++;
            i = j - 1;
        }
        n = s2.size();
        for(int i = 0; i < n; ++ i)
        {
            int j = i + 1;
            while(j < n && s2[j] == s2[j-1] + 1) j ++;
            res ++;
            i = j - 1;
        }
        
        return res;
    }
};

其实把相邻且重复的元素去重就OK了

class Solution {
public:
    int countHillValley(vector<int>& nums) {
        int n = nums.size();
        vector<int> t;
        t.emplace_back(nums[0]);
        for(int i = 1; i < n; ++ i) if(nums[i] != nums[i-1]) t.emplace_back(nums[i]);

        int res = 0;
        n = t.size();
        for(int i = 1; i < n - 1; ++ i)
            if((t[i] - t[i-1]) * (t[i + 1] - t[i]) < 0) 
                res ++;
        
        return res;
    }
};

T2

分情况讨论下即可。

下图是我比赛时的手稿:

然后依照这个模拟下就出来了

class Solution {
public:
    //撞了就变静止
    int countCollisions(string s) {
        int n = s.size();
        int res = 0;
        int sum = 0;
        //从左往后
        for(int i = 0; i < n; ++ i)
        {
            if(s[i] == 'R') 
                sum ++;
            else if(s[i] == 'L')
            {
                if(sum)
                {
                    res += sum + 1;
                    s[i] = 'S';
                    sum = 0;                    
                }
            }
            else if(s[i] == 'S')
            {
                res += sum;
                sum = 0;
            }
        }
        
        //从右往左
        sum = 0;
        for(int i = n - 1; i >= 0; -- i)
        {
            if(s[i] == 'L') sum ++;
            else if(s[i] == 'R')
            {
                if(sum)
                {
                    res += sum + 1;
                    s[i] = 'S';
                    sum = 0;                    
                }

            }
            else if(s[i] == 'S')
            {
                res += sum;
                sum = 0;
            }
        }
        
        return res;
    }
};

T3

抓住区域的数量只有12个,状态压缩枚举每种情况即可。

class Solution {
public:
    vector<int> t;
    //状态压缩
    //先判断每种得分情况是否可行, 再计算最终得分
    vector<int> maximumBobPoints(int num, vector<int>& a) {
        t.resize(12);
        int maxn = 0;
        vector<int> ans;
        for(int i = 1; i < (1 << 12); ++ i)
        {
            //每一种得分情况
            if(check(i, num, a))
            {
                int tmp = 0;
                for(int j = 0; j < 12; ++ j)
                    if((i >> j) & 1) tmp += j;
                if(tmp > maxn)
                {
                    maxn = tmp;
                    ans = t;
                }
            }
        }
        return ans;
    }
    
    bool check(int u, int num, vector<int> & a)
    {
        //先把所有地方+1 再随便找一个地方+剩余
        int y = 0;
        for(int &i : t) i = 0;
        for(int i = 0; i < 12; ++ i)
        {
            if((u >> i) & 1)
            {
                t[i] = a[i] + 1;
                y += t[i];
            }
        }
        
        if(y < num)
        {
            for(int i = 0; i < 12; ++ i)
            {
                if((u >> i) & 1)
                {
                    t[i] += num - y;
                    return true; //true
                }
            }       
        }
        
        if(y > num) return false;
        return true;
    }
};

T4暂时不会,先放着吧。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值