LeetCode 第 309 场周赛 程序精注

题目列表

赛后总结

总体上来看自己的基础不够扎实。

6167.检查相同字母间的距离

明明的确是一道简单题,就是能把last[ni] == -1 打成 last[ni] = -1 还嗯是反复查错了半天没查出来,静态查错的能力真的挺重要的,可惜没能养成检查的好习惯。顺便一提,开始时想起来Python是用Unicode码和字符进行转换的,当时想到这还愣了一下。

6168.恰好移动 k 步到达某一位置的方法数目

高数基础考试没有考组合数,结果在这里的第二题考了,考试时看出来了要用数学推导,但是把情况复杂化了,想着去分成SP左边、SP-EP和EP右边分别做推导然后再用类组合数推导求解,果然眼界还是比较小。代码也是乱糟糟的,事后几乎没法还原。

6169.最长优雅子数组

又到了每日跪给位运算的时间了,虽然现学了一个 (A & B) | C == (A & B) | (A & C) 但完全只是为了用而用,完全没有去真正的从位运算的方面去想。因此没有发现“对于每一组解,所有的二进制位上只能出现一个1”(这么基础的东西都没能想到也是真的菜),“对于本题目数据范围,优雅数组的最长长度为30”(对于Python语言来说只是安慰剂)。

6170.会议室 III

完全被那个“困难”标签唬住了。其实这题的数据范围就算直接用暴力排序都能做。Python的自带堆更是看完题解现学的。

正确的代码

6167.检查相同字母间的距离

class Solution:
    def checkDistances(self, s: str, distance: List[int]) -> bool:
        last = [-1] * (26)
        for i in range(len(s)):
            ni = ord(s[i]) - ord('a')
            if last[ni] == -1:
                #print("@",i,ni,last[ni])
                last[ni] = i
            elif i - last[ni] - 1 != distance[ni]:
                #print(i - last[ni] - 1 , distance[ni])
                return False
            else:
                #print(i - last[ni] - 1 , distance[ni])
                last[ni] = i
        return True

6168.恰好移动 k 步到达某一位置的方法数目

class Solution:
    def numberOfWays(self, startPos: int, endPos: int, k: int) -> int:
        # 组合数这么明显的方法都没想到,我果然还是个傻子
        # 从startPos 到 endPos 明显只有向左走和向右走
        # 由于向左走和向右走的步数是固定的,只需要用组合数求出
        # 到底是哪几步是向一个方向走的选择就行了
        if abs(endPos - startPos) > k:
            return 0
        if (k - abs(endPos - startPos)) % 2 != 0:
            return 0
        tokimeki = [0] *(k+5)
        for i in range(len(tokimeki)):
            tokimeki[i] = [0] * (k+5)
            tokimeki[i][0] = 1
        HONOKA = 10 ** 9 + 7
        for i in range(k + 1):
            for j in range(1,min(i,(k - abs(endPos - startPos))//2)+1):
                tokimeki[i][j] = (tokimeki[i-1][j-1] + tokimeki[i-1][j]) % HONOKA
        #print(tokimeki)
        return tokimeki[k][(k - abs(endPos - startPos))//2]

6169.最长优雅子数组

class Solution:
    def longestNiceSubarray(self, nums: List[int]) -> int:
        # 每一对元素按位与的运算结果均为0 -> 
        #    对于每一组解,所有的二进制位上只能出现一个1,
        #    也就是说对于本题目数据范围,优雅数组的最长长度为30。
        # 根据位运算的性质,(A & B) | C == (A & B) | (A & C) ->
        #    可以用一个OR变量储存之前所有数的或运算,这样无需遍历全部数字,
        #    由于性质1,对于一个合法的OR变量,或运算视为无损压缩,
        #    故对于合法的OR变量,可以进行异或运算以去除之前的某个数
        # 由于性质2以及子数组的连续性,我们可以使用双指针,指定左侧边界
        l = 0
        ans = 0
        cur = 0
        for r in range(len(nums)):
            while nums[r] & cur :
                cur ^= nums[l]
                l += 1
            cur |= nums[r]
            if r - l + 1 > ans:
                ans = r - l + 1
        return ans

6170.会议室 III

class Solution:
    def mostBooked(self, n: int, meetings: List[List[int]]) -> int:
        # 原来只是加了堆的模拟,(经典早知道)在比赛的时候应该先交个暴力排序先试试的
        # 用两个小根堆 idle (i) 和 busy (endTime,i) 储存空闲和繁忙的会议室
        # 由于会议的时间是线性的,开始时间严格不同且优先处理开始时间最早的会议
        #     故可以先对所有会议按照开始时间进行排序
        # 在处理一个会议之前,先把所有已经开完会的会议室腾出来,
        #     具体方法就是用堆的heappop弹出结束时间早于当前时间(注意左闭右开)会议
        # 之后取出尚未占用且编号最小的会议,
        #     注意特判:如果所有的会议室均已被占用,替代为弹出结束时间最早的
        #     正在开会的会议室,并在更新结束时间之后将其放回正在开会的会议室
        idle = list(range(n))
        busy = []
        cnt = [0] * (n)
        meetings.sort()
        for i in meetings:
            while busy and busy[0][0] <= i[0]:
                heappush(idle,heappop(busy)[1])
            if len(idle) == 0:
                ti, no = heappop(busy)
                ti += (i[1] - i[0])
            else:
                no = heappop(idle)
                ti = i[1]
            cnt[no] += 1
            heappush(busy,(ti,no))
        ans = 0
        ansi = 0
        for i, c in enumerate(cnt):
            if c > ans:
                ans = c
                ansi = i
        return ansi

其他的碎碎念

后知后觉的感悟

  • 秋招也好,米哈游也罢,其实参加每场周赛的人数都是相对稳定的,之前总是有一种“啊,金九银十了,一定会有不少人临阵抱佛脚”的奇怪想法;
  • 排名总是会掉的,毕竟还是小菜只因,之后实打实地练到1700以上,然后再去参加灵神的刷题群吧;
  • 今天蹲了一整天的图书馆机房,只打了几道题,难度系数还远没之前OI的高;不过挺快乐的,就当是另一种形式的休息了。

无聊的程序模板

老实说作用有限,不过连带变量直接复制题目里的数据,然后粘贴进去还是做得到的。

###################################
# for Contest : LeetCode Week 309
# Problem No. : D
# Title       : 
###################################

class Solution:
    def main():
        pass

if __name__ == "__main__":
    sol = Solution()
    sol.main()

错误程序挂路灯

6168.恰好移动 k 步到达某一位置的方法数目

半成品程序,简单问题复杂化

class Solution:
    def numberOfWays(self, startPos: int, endPos: int, k: int) -> int:
        # 变量初始化
        HONOKA = 10 ** 9 + 7
        dp = [ [0] * (k + 5) ] * (k + 5)
        ans = 0
        # dp计算函数
        def lovelive(rang, step):
            nonlocal dp,HONOKA
            res = 0
            if rang == 0:
                return 0
            if dp[rang][step] != 0:
                return dp[rang][step]
            if rang == 1:
                if step % 2 == 1:
                    dp[rang][step] = 1
                else:
                    dp[rang][step] = -1
                return dp[rang][step]
            for i in range(1,rang):
                for j in range(i,step - (rang - i) + 1,2):
                    l = lovelive(i,j)
                    r = lovelive(rang - i,step - j)
                    if l == -1 or r == -1:
                        continue
                    res = (res + l * r) % HONOKA
            return res
        # 主算法
        # 特判
        if k - abs(startPos - endPos) < 0 : 
            return 0
        if (k - abs(startPos - endPos)) % 2 != 0:
            return 0
        # 求解
        side = (k - abs(startPos - endPos)) // 2
        for lside in range(0,side + 1):
            # 确定左右需要处理的溢出数量
            rside = side - lside
            for sstep in range(side * 2,k - abs(startPos - endPos) + 1,2):
                for lstep in range(lside * 2,sstep - rside):
                    rstep = sstep - lstep
                    lans = lovelive(lside,lstep)
                    rans = lovelive(rside,rstep)
                    mans = lovelive()

6169.最长优雅子数组

现学的还会WA,WA了还调不出来,真的就是个菜只因。

class Solution:
    def main(self):
        nums = [744437702,379056602,145555074,392756761,560864007,934981918,113312475,1090,16384,33,217313281,117883195,978927664]
        print(self.longestNiceSubarray(nums))

    def longestNiceSubarray(self, nums: list[int]) -> int:
        def lovelive(leng):
            nonlocal nums
            for i in range(leng - 1,len(nums)):
                print(i,i - leng + 1,end=" ")
                curHuo = nums[i - leng + 1]
                flag = True
                for j in range(i - leng + 2,i + 1):
                    if nums[j] & curHuo != 0:
                        flag = False
                        break
                if flag : 
                    print(True)
                    return True
                print("\t| ",end="")
            print(False)
            return False
        l = 1
        r = len(nums)
        while l < r:
            mid = (l + r + 1) // 2
            if lovelive(mid):
                print("\t",mid,True)
                l = mid
            else:
                print("\t",mid,False)
                r = mid - 1
        return l
知识共享许可协议
《LeetCode 第 309 场周赛 程序精注》在文章中没有特殊说明的情况下采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。请在转载时注明作者(从现瑕疵)和来源(https://www.zhtg.net.cn/leetcode-weekly-contest-309/)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇