力扣第261场周赛题解

本文分享了力扣第261场周赛的解题思路,涉及贪心策略。针对2027题,通过保证相邻字符中至少有一个X来减少操作次数。2028题中,通过计算所需点数判断解的存在性,并逐步调整筛子数值。2029题,分析石子按3的余数可分为三类,探讨先手优势情况。每道题均提供AC代码。

2027 转换字符串的最少操作次数
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
【贪心】因为对OOO操作没有意义,只会白白增加操作数,所以我们需要保证相邻的3个字符中至少有一个X,对于第一个X(假设在第i位),我们需要将其变为O(必定要操作),可以第从i - 2位、i - 1位、i位开始操作,如果我们从第i位开始,可以保证至少i + 2位没有X,且无后效性,所以我们每次取第一个X作为开始点,然后进行操作
AC代码:

class Solution {
public:
    int minimumMoves(string s) {
        int n = s.size(),ans = 0;
        for(int i = 0;i < n;i ++)
            if(s[i] == 'X')
             {
                 ans ++;
                 i += 2;
             }
        return ans;
    }
};

2028 找出缺失的观测数据
在这里插入图片描述
在这里插入图片描述
【贪心】通过计算我们可以得出我们需要的点数,即:平均数 * 筛子数 - 已有的数(mean × (n + m) - sum;)然后我们可以很容易得出是否有解,即:我们需要的筛子能不能达到要求。若所有的筛子都是6仍小于需要的数或者所有的筛子都为1仍大于需要的数则无解。若有解,我们采取先把所有的筛子设为一,然后依次把前面的筛子设置为6,若某一时刻剩下的筛子不足5(刚开始已经设置了1),则该筛子为1 + 剩余的值
AC代码:

class Solution {
public:
    vector<int> missingRolls(vector<int>& rolls, int mean, int n) {
        int m = rolls.size(),sum = 0;
        vector<int> ans; 
        for(int i = 0;i < m;i ++)
            sum += rolls[i];
        int needs = mean * (n + m) - sum;
        if(needs < n||needs > 6 * n) return ans;
        needs -= n;
        for(int i = 0;i < n;i ++)
        {
            if(needs >= 5) ans.push_back(6);
            else ans.push_back(1 + needs);
            needs -= 5;
            if(needs < 0) needs = 0;
        }
        return ans;
    }
};

2029 石子游戏 IX
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
【贪心】可以很容易看出,我们拿到的石子x只有3类(x % 3 = 0;x % 3 = 1;x % 3 = 2)分别将其记做a,b,c。
一、先假设a = 0.
① 先手拿b,则后续只能为b->b->c->b->c……
② 先手拿c,则后续只能为c->c->b->c->b……

则很容易可以看出先手可以控制每个人拿什么石子,若2种石子都有,则先手拿较少的一种(或相同)则必胜(先手先拿的种类为对方需要每次拿的种类),若只有1种石子,根据顺序我们发现先手必败。
同时扩展a为偶数,因为比赛过程中(非第一步)取3的倍数的石子一定不会输掉比赛,先手完全可以再取一次a把轮次调整回来

二、a为奇数(偶数已经经过一、扩展了)
a为奇数意味着先取a的人有一次调整轮次的机会,且此次机会不能在第一轮使用,也就是说调整轮次的机会为后手优先。
①后手取调整轮次
由于先手可以控制每个人拿的石子,但后手会调整轮次,使双方的石子发生变化,则先手会拿较多的石子,这样做会使自己额外失去2个石子,且需要确保使石子不能恰好被取完(即其中一个会比另一个至少大3)若对方不调整轮次,则我方调整对我方更有利(节省了1枚石子)
②先手调整轮次
经①分析,先手不会获得调整轮次的机会
AC代码:

class Solution {
public:
    bool stoneGameIX(vector<int>& st) {
        int a = 0,b = 0,c = 0;
        int n = st.size();
        for(int i = 0;i < n;i ++)
        {
            if(st[i] % 3 == 0) a ^= 1;
            else if(st[i] % 3 == 1) b ++;
            else c ++;
        }
        if(!a)
        {
            if(!b||!c) return false;
            return true;
        }
        else
        {
            if(b - 2 > c||c - 2 > b) return true;
            return false;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值