【力扣周赛】第 363 场周赛(完全平方数和质因数分解)

2023-09-17 13:55:13

竞赛链接

https://leetcode.cn/contest/weekly-contest-363/

Q1:100031. 计算 K 置位下标对应元素的和

https://leetcode.cn/problems/sum-of-values-at-indices-with-k-set-bits/
在这里插入图片描述

提示:
1 <= nums.length <= 1000
1 <= nums[i] <= 10^5
0 <= k <= 10

竞赛时代码

class Solution {
    public int sumIndicesWithKSetBits(List<Integer> nums, int k) {
        int ans = 0;
        for (int i = 0; i < nums.size(); ++i) {
            if (Integer.bitCount(i) == k) ans += nums.get(i);
        }
        return ans;
    }
}

写法2——手写二进制中1的数量

class Solution {
    public int sumIndicesWithKSetBits(List<Integer> nums, int k) {
        int ans = 0;
        for (int i = 0; i < nums.size(); ++i) {
            if (cnt(i) == k) ans += nums.get(i);
        }
        return ans;
    }

    public int cnt(int x) {
        int res = 0;
        while (x != 0) {
            res++;
            x &= x - 1;
        }
        return res;
    }
}

Q2:100040. 让所有学生保持开心的分组方法数(排序后枚举分界)

https://leetcode.cn/problems/happy-students/description/
在这里插入图片描述
提示:
1 <= nums.length <= 10^5
0 <= nums[i] < nums.length

竞赛时代码

将学生排序后, 一个学生 x 被选了的时候,比它小的一定必须被选;同理一个学生 y 不被选的时候,比它大的一定不能被选。

枚举每个位置,假设 0~i 被选择,i+1~n-1 不被选择。检查是否合理,合理则 ans ++;

class Solution {
    public int countWays(List<Integer> nums) {
        // 按题意——一定先选择nums值更小的学生,所以——从小到大排序
        Collections.sort(nums);
        int n = nums.size(), ans = 0;
        if (nums.get(0) > 0) ans++;     // 处理特例是否可以全不选
        // 枚举选择到每个位置
        for (int i = 0; i < n; ++i) {  
            // 检查已经选择人数i+1是否严格大于nums[i]
            if (i + 1 > nums.get(i)) { 
                // 检查已经选择人数i+1是否严格小于下一个没被选择的学生nums[i+1]  (注意要判断越界)
                if (i + 1 < n && nums.get(i + 1) <= i + 1) continue;    // 不满足就跳过
                ans++;  // 这个位置合理,答案+1
            }
        }
        return ans;
    }
}

Q3:100033. 最大合金数(二分答案)

https://leetcode.cn/problems/maximum-number-of-alloys/description/

在这里插入图片描述
提示:
1 <= n, k <= 100
0 <= budget <= 10^8
composition.length == k
composition[i].length == n
1 <= composition[i][j] <= 100
stock.length == cost.length == n
0 <= stock[i] <= 10^8
1 <= cost[i] <= 100

竞赛时代码

注意到题目中说明——“所有合金都需要由同一台机器制造。”,且观察到 k 的数据范围较小,所以可以枚举使用每台机器。
对于每台机器,使用二分查找求出它可以制造出的最大的合金数量。

二分查找时判断的依据是花费的前有没有在 budget 的范围内。

class Solution {
    public int maxNumberOfAlloys(int n, int k, int budget, List<List<Integer>> composition, List<Integer> stock, List<Integer> cost) {
        long ans = 0;
        // 按照题意,所有合金都需要由同一台机器制造。枚举每个机器。
        for (int i = 0; i < k; ++i) {
            ans = Math.max(ans, op(n, budget, composition.get(i), stock, cost));
        }
        return (int)ans;
    }
    
    // 计算使用某台机器时的最大制造数量
    public long op(int n, int budget, List<Integer> composition, List<Integer> stock, List<Integer> cost) {
        // 二分答案
        long l = 0, r = (long)Integer.MAX_VALUE;
        while (l < r) {
            long mid = l + r + 1 >> 1;
            if (check(mid, n, budget, composition, stock, cost)) l = mid;
            else r = mid - 1;
        }
        return l;
    }
    
    // 检查是否可以造出 k 个合金
    public boolean check(long k, int n, int budget, List<Integer> composition, List<Integer> stock, List<Integer> cost) {
        long s = 0;     // 记录额外花费
        for (int i = 0; i < n; ++i) {
            long need = k * composition.get(i);
            if (need <= stock.get(i)) continue;
            s += cost.get(i) * (need - stock.get(i));
            if (s > budget) return false;   // 额外花费超了,不能造出k个合金
        }
        return true;
    }
}

Q4:8041. 完全子集的最大元素和

https://leetcode.cn/problems/maximum-element-sum-of-a-complete-subset-of-indices/description/

在这里插入图片描述
提示:
1 <= n == nums.length <= 10^4
1 <= nums[i] <= 10^9

竞赛时代码——质因数分解+哈希表

对每个下标质因数分解,两两相乘之后的结果是完全平方数,那么这两个数字的质因数分解的奇偶性相同。 例如2=21,8=23;相同质因数出现的次数的奇偶性相同,则两者可以匹配。

根据质因数分解的结果将所有数字分组即可。

class Solution {
    public long maximumSum(List<Integer> nums) {
        // 两两之间相乘之后是完全平方数,则质因数分解结果满足各个质因数数量奇偶性相同
        int n = nums.size();
        String[] mask = new String[n];
        long ans = 0;
        // key是mask,value是sum
        Map<String, Long> m = new HashMap<>();     
        for (int i = 1; i <= n; ++i) {
            mask[i - 1] = op(i);                                        // 计算mask
            m.merge(mask[i - 1], (long)nums.get(i - 1), Long::sum);     // 求和
            ans = Math.max(ans, m.get(mask[i - 1]));                    // 更新答案
        }
        return ans;
    }
    
    // 计算下标x的质因数分解掩码mask
    public String op(int x) {
        // 将质因数的数量为奇数的部分记录下来
        String mask = "";
        for (int i = 2; i <= x / i; ++i) {
            if (x % i == 0) {
                int s = 0;
                while (x % i == 0) {
                    s++;
                    x /= i;
                }
                if (s % 2 == 1) mask += String.valueOf(i) + " ";
            }
        }
        if (x > 1) mask += String.valueOf(x) + " ";
        return mask;
    }
}

解法2——定义core(x)为 x 除去完全平方因子后的剩余结果

https://leetcode.cn/problems/maximum-element-sum-of-a-complete-subset-of-indices/solutions/2446037/an-zhao-corei-fen-zu-pythonjavacgo-by-en-i6nu/

计算方式同质因数分解,把 n 的所有出现次数为奇数的质因子相乘,即为 core(n)。

class Solution {
    public long maximumSum(List<Integer> nums) {
        // 两两之间相乘之后是完全平方数,则质因数分解结果满足各个质因数数量奇偶性相同
        int n = nums.size();
        long[] sum = new long[n + 1];
        long ans = 0;
 
        for (int i = 1; i <= n; ++i) {
            int c = op(i);                 // 计算mask
            sum[c] += nums.get(i - 1);     // 求和
            ans = Math.max(ans, sum[c]);   // 更新答案
        }
        return ans;
    }
    
    // 计算下标x的质因数分解掩码mask
    public int op(int x) {
        // 将质因数的数量为奇数的部分记录下来
        int res = 1;
        for (int i = 2; i <= x / i; ++i) {
            if (x % i == 0) {
                int s = 0;
                while (x % i == 0) {
                    s++;
                    x /= i;
                }
                if (s % 2 == 1) res *= i;
            }
        }
        if (x > 1) res *= x;
        return res;
    }
}

成绩记录

在这里插入图片描述
T4 没有那么难!想得慢了!

在这里插入图片描述

更多推荐

【音视频原理】音视频 “ 采样 - 编码 - 封装 过程 “ 和 “ 解封装 - 解码 - 播放 过程 “ 分析 ( 视频采集处理流程 | 音频采集处理流程 | 音视频文件解封装播放流程 )

文章目录一、视频采集处理流程二、音频采集处理流程三、音视频文件解封装播放流程本篇文件主要分析音视频文件是怎么产生的,以及音视频文件是如何播放的;一、视频采集处理流程视频文件从录像到生成文件的全过程:采集图像帧:摄像头硬件负责采集画面,采集的初始画面称为"图像帧",一秒钟采集的图像帧数量称为"帧率",如:60帧就是一秒钟

网络安全(黑客)自学

目录:一、什么是网络安全二、怎样规划网络安全三、网络安全的知识多而杂,怎么科学合理安排?1、基础阶段2、渗透阶段3、安全管理(提升)这一阶段主要针对已经从事网络安全相关工作需要提升进阶成管理层的岗位。如果你只学习参加工程师方面的岗位,这一阶段可学可不学。4、提升阶段(提升)1、Web安全相关概念(2周)2、熟悉渗透相关

Web Components详解-Shadow DOM基础

目录引言概念基本用法attachShadow函数mode(模式)delegatesFocus(委托聚焦)CustomElements+ShadowDOM基本用法样式及属性隔离写在最后相关代码参考文章引言上篇文章的自定义标签中,我们使用customElements对象对原生标签进行拓展,达到组件的拓展性与复用性的效果,那

Spring Boot集成EasyExcel实现数据导出

在本文中,我们将探讨如何使用SpringBoot集成EasyExcel库来实现数据导出功能。我们将学习如何通过EasyExcel库生成Excel文件,并实现一些高级功能,如支持列下拉和自定义单元格样式,自适应列宽、行高,动态表头,以及如何同时导出多个sheet页的数据。引入依赖首先,我们需要在pom.xml文件中添加E

【前端系列】前端如何使用websocket发送消息

序言今天来学习一下前端如何使用websocket发送消息1基础介绍1.1什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工通信的协议,它可以让客户端和服务器之间进行实时的双向通信。与传统的HTTP请求不同,WebSocket使用了一个长连接,在客户端和服务器之间保持持久的连接,从而可以实时地发

TCP 和 UDP 的 Socket 调用

在网络层,Socket函数需要指定到底是IPv4还是IPv6,分别对应设置为AF_INET和AF_INET6。另外,还要指定到底是TCP还是UDP。TCP协议是基于数据流的,所以设置为SOCK_STREAM,而UDP是基于数据报的,因而设置为SOCK_DGRAM。TCP的服务端要先监听一个端口,一般是先调用bind函数

若依框架集成WebSocket带用户信息认证

一、WebSocket基础知识我们平时前后台请求用的最多的就是HTTP/1.1协议,它有一个缺陷,通信只能由客户端发起,如果想要不断获取服务器信息就要不断轮询发出请求,那么如果我们需要服务器状态变化的时候能够主动通知客户端就需要用到WebSocket了,WebSocket是一种网络传输协议,同样也位于OSI模型的应用层

c++学习之十四

1)利用std::function实现回调函数,实现生产者及消费者模型//254、回调函数的实现//在消息队列和网络库的框架中,当接收到消息(报文)时,回调用户自定义的函数对象,把消息(报文)参数传给它,由它决定如何处理。//示例://254、回调函数的实现//在消息队列和网络库的框架中,当接收到消息(报文)时,回调用

【2023】Redis相关面试题

1.Redis是什么?它有什么特点?答:Redis是一个使用C语言编写的开源、高性能、支持多种数据结构的NoSQL数据库。支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等。数据存储在内存中,可以快速读写。支持数据持久化,可以将数据保存到磁盘上。提供了丰富的功能,如发布订阅、事务、Lua脚本等。具有高可用性和可

jvm面试题

jvm内存区域Q:jvm内存区域怎么划分的?答:堆内存(线程共享):所有线程共享的一块区域,垃圾收集器管理的主要区域。主要存储对象、数组。Java堆中还可以细分为:新生代和老年代;再细致一点的有Eden空间、FromSurvivor空间、ToSurvivor空间等,默认情况下新生代按照8:1:1的比例来分配。程序计数器

IMX6ULL ARM Linux开发板SD卡启动,SD卡的分区与分区格式化创建

一、确定TF卡挂载到ubuntu上的设备名称及分区情况1.在ubuntu不接入TF卡的情况下,使用df-lh/dev/sd*命令查看当前"/dev/sd开头"的设备。##输入df-lh/dev/sd*命令,敲回车键~$df-lh/dev/sd*2.将TF卡接入到ubuntu,再次使用df命令,进行查看,多出来的设备即是

热文推荐