基础贪心算法集合2(10题)

news2025/4/16 3:07:51

目录

1.单调递增的数字

2.坏了的计算器

 3.合并区间

4.无重叠区间

5. 用最少数量的箭引爆气球

 6.整数替换

解法1:模拟+记忆化搜索

解法2位运算+贪心

7.俄罗斯套娃信封问题

补充.堆箱子

8.可被3整除的最大和

 9.距离相等的条形码

 10.重构字符串


1.单调递增的数字

 738. 单调递增的数字 - 力扣(LeetCode)

但是如果只这么处理会出现bug 

例如如下这种情况,我们需要找到最前面的5.

因此

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string num = to_string(n);
        int sz = num.size();
        int i = 0;
        while(i+1 < sz && num[i] <= num[i+1])i++;
        if(i+1 == sz)return n;//如果全递增直接返回,或者处理nums[i]的时候判断一下
        while(i - 1 >= 0 && num[i-1] == num[i])i--;
       num[i]--;
        for(int k = i + 1; k < sz; k++)
        {
            num[k] = '9';
        }
        return stoi(num);//std::stoi 会忽略前导零,只返回字符串表示的整数值
    }
};

2.坏了的计算器

 991. 坏了的计算器 - 力扣(LeetCode)

看到这题我们首先就想到正向推导。

我们贪心地想到,如果想让初始数字以尽可能少的次数变成目标数字,可以多用*2操作。

但是我们发现这种贪心是不对的,对于*2和-1的操作,判断标准不是很明确。 用正向的方法比较难解决这个问题

        于是我们想到正难则反,而*2 和-1的操作正好有相反的/2和+1操作。 

        这一题有个非常重要的点就是它里面的数据是没有小数的,从起始数据到目标数据,不断*2,-1操作下是不能产生小数的。

          所以我们在面对奇数的时候,就不能进行/2操作了,只能进行+1操作。

整理思路,我们得出以下结论:

1.当end <= begin

当 end <= begin时,end要想达到begin,肯定不可能进行/2操作,只能进行+1操作,这时候无论奇数偶数,都只有+1的选择。我们需要进行begin-end次操作

 2.当end > begin 的时

当end > begin 的时候

 我们如果想要先+1再/2,那么我们必须要加偶数个1,我们才能/2.最后,我们通过k+1次操作得到了(x+k)/2.

而如果我们先/2,那么我们只需要1+k/2 次就能得到(x+k)/2。

我们很容易得到先进行除法是更优的。

因此在end > begin的时候 ,我们奇数仍然是只能+1,偶数则是只进行/2操作

class Solution {
public:
    int brokenCalc(int startValue, int target) {
        int ret = 0;
        while(target > startValue)
        {
            if(target % 2 == 0)
            {
                target /= 2;
                ret++;
            }
            else
            {
                target++;
                ret++;
            }
        }
        ret += startValue - target;
        return ret;
    }
};

 3.合并区间

56. 合并区间 - 力扣(LeetCode)

区间问题解法

我们为了思路统一,统一采用左端点排序

 假设我们有一个区间,从left 到right

那么我们下一个区间有以下这些情况。

整体分为有重叠部分和没有重叠部分。

当有重叠部分时,我们保存左端点,取较大的右端点。(因为进行排序后,左端点是升序排序的)

当没有重叠部分时,我们把{left,right}加入ret数组,然后更新left和right。

class Solution {
public:
    static bool cmp(vector<int> a, vector<int> b)
    {
        return a[0] < b[0];
    }
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        //排序
        sort(intervals.begin(), intervals.end(), cmp);
        //合并区间
        vector<vector<int>> ret;
        int left = intervals[0][0];
        int right = intervals[0][1];
        for(int i = 1; i < intervals.size(); i++)
        {
            if(intervals[i][0] <= right)//有重叠部分
            {
                right = max(right,intervals[i][1]);//合并
            }
            else//无重叠
            {
                ret.push_back({left, right});//加入到结果中
                left = intervals[i][0];
                right = intervals[i][1];
            }
        }
        ret.push_back({left, right});
        return ret;
    }
};

4.无重叠区间

 435. 无重叠区间 - 力扣(LeetCode)

 

仍然是先按照左端点排序。

我们要移除最少的区间,那也就是说要保留更多的区间。

因此我们可以采用以下策略来保留更多区间。

当存在区间重叠时,我们保留较小的右端点,这样它和后面的 区间有重叠的可能性就会变小。

当区间无重叠,我们更新left right并把count++即可。

遍历数组结束后要记得加上最后存在left right里面的那段区间。

最后,因为我们求的是移除的区间,因此把数组的长度减去count就是我们的返回值

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        int count = 0;
        sort(intervals.begin(), intervals.end());
        
        int left = intervals[0][0];
        int right = intervals[0][1];
        for(int i = 1; i < intervals.size(); i++)
        {
            if(intervals[i][0] < right)
            {
                right = min(right,intervals[i][1]);
            }
            else
            {
                count++;
                left = intervals[i][0];
                right = intervals[i][1];
            }
        }
        count ++;
        return intervals.size() - count;
    }
};

5. 用最少数量的箭引爆气球

452. 用最少数量的箭引爆气球 - 力扣(LeetCode)

理解题意,我们发现这也是一个区间问题。

我们发现这题找的实际上是交集。

  

class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        sort(points.begin(), points.end());
        int cover = 0;
        int right = points[0][1];
        for(int i = 1; i < points.size(); i++)
        {
            if(points[i][0] <= right)//和上一个区间有交集
            {
                cover++;//重叠部分++
                right = min(right, points[i][1]);//右端点较小的同时也是是重叠区间的右端点
            }
            else
            {
                right = points[i][1];//无交集,以新的区间为基准再求重叠部分
            }
        }
        return points.size() - cover;
    }
};

 6.整数替换

解法1:模拟+记忆化搜索

就是暴力枚举每种情况,对于偶数直接除以2,对于奇数则是取 min(hash[n-1], hash[n+1])

需要注意的地方是,为了防止INT_MAX + 1 溢出,我们dfs函数的类型使用long long,哈希表也是一样。

class Solution {
public:
    unordered_map<long long, int> hash;
    int integerReplacement(int n) {
       
        return dfs(n);
    }
    int dfs(long long n)
    {
        if(n == 1)return 0;
        if(n % 2 == 0)
        {
            if(!hash.count(n/2))
            {
                hash[n/2] = dfs(n/2);
            }
            return 1 + hash[n/2];
        }
        else
        {
            if(!hash.count(n+1) )
            {
                hash[n+1] = dfs( n+1 );
            }
            if(!hash.count( n-1 ) )
            {
                hash[ n-1 ] = dfs( n-1 );
            }
            return 1  + min(hash[n-1], hash[n+1]);
        }
    }
};

解法2位运算+贪心

对于偶数我们进行/2操作即可。

对于奇数操作, 当其为01结尾的时候,我们采用-1操作操作数会更少。

                                当其为11结尾的时候,-1操作会使得一位1变为0,而+1操作可能会使得多于一位的1变为0,因此采用+1的操作会更快捷地得到最终值。

最后有一个例外,即3,我们应该采用-1操作。

要判断最后两位是01还是11,我们只需要把这些数对4取余即可,看余数是1还是3即可判断。

这道题的贪心就贪在不同的奇数是+1还是-1,已经在过程中证明好了

 同样需要加一个longlong

class Solution {
public:
    int integerReplacement(int num) {
        int ret = 0;
        long long n = num;
        while(n > 3)
        {
            if(n % 2 == 0)
            {
                ret++;
                n  = n >> 1;
            }
            else
            {
                if(n % 4 == 3)
                {
                    n = n + 1;
                    ret++;
                }
                else if(n % 4 == 1)
                {
                    n = n - 1;
                    ret++;
                }

            }
        }
        if(n == 3)return ret + 2;
        else if(n == 2)return ret + 1;
        else return ret;
    }
};

7.俄罗斯套娃信封问题

 解法1:区间排序+动态规划(超时)

解法2:区间排序 + 贪心 + 二分

我们严格按照左端点排序后,实际上已经不用看左端点了,因为总是递增的。 

那么这道题经过这样处理,就变成了一个最长递增子序列问题。

 

        但是当左端点有重复的时候需要注意,这时候如果我们的右端点按照升序排,我们就会把一些不该加的元素加入。

         这时候就需要我们在左端点相同的时候把右端点降序排序

 

        这样的好处是,我们就不会有可能把这些数字全部接到原数组后面了。因为如果有更小的数,那么我们会将其与原来的数替换。例如上一个数是3,按照升序排序的话,4679都会排到它后面。

        可是如果我们降序,则我们在将9加入数组后,后面的764都只是更新数组末尾的9而已,让9不断被替换为764.

class Solution {
public:
    static bool cmp(const vector<int> & a, const vector<int> & b)
    {
        if(a[0] != b[0])return a[0] < b[0];
       else return a[1] > b[1];
    }
    int maxEnvelopes(vector<vector<int>>& env) {
        sort(env.begin(), env.end(), cmp);
        vector<int> ret;
        ret.push_back(env[0][1]);
        for(int i = 1; i < env.size(); i++)
        {
            if(env[i][1] > ret.back())
            {
                ret.push_back(env[i][1]);
            }
            else
            {
                int left = 0; 
                int right = ret.size() - 1;
                while(left < right)
                {
                    int mid = left + (right-left) / 2;
                    if( env[i][1] <= ret[mid])
                    {
                        right = mid;
                    }
                    else{
                        left = mid + 1;
                    }
                }
                ret[left] = env[i][1];
            }
        }
        return ret.size();
    }
};

补充.堆箱子

 虽然俄罗斯套娃信封中的解法1会超时,但是在堆箱子这题中是可以通过的

面试题 08.13. 堆箱子 - 力扣(LeetCode)

 排序后的思路和最长递增子序列相同

有两个需要注意的问题

class Solution {
public:
    static bool cmp(vector<int> a, vector<int> b)
    {
        return a[0] < b[0];
    }
    int pileBox(vector<vector<int>>& box) {
        sort(box.begin(), box.end(),cmp);//1.需要自己手动写一个排序函数,按照某一维度来排。 
                                          //默认排序会出问题
        int n = box.size();
        if(n == 0)return 0;
        vector<int> dp(n , 0);
        for(int i = 0; i < n; i++)//2.初始化dp表的时候,每个箱子最小的堆叠高度是自己的高度
        {
            dp[i] = box[i][2];
        }
        int ret = dp[0];
        for(int i = 1; i < n; i++)
        {
            for(int j = i - 1; j >= 0; j--)
            {
                if(box[j][0] < box[i][0] && box[j][1] < box[i][1] && box[j][2] < box[i][2])
                {
                    dp[i] = max(dp[i], dp[j] + box[i][2]);
                }
            }
            ret = max(ret, dp[i]);
        }
        return ret;
    }
};

8.可被3整除的最大和

 1262. 可被三整除的最大和 - 力扣(LeetCode)

 

我们正难则反,根据累加和的不同情况,删去一些数即可,而我们只需要贪心地删除最小值即可。  

        分类情况中, 我们把第二种情况拿来举例子,可能我们有1个或者4个或者7个除以3余1的数,但是我们只需要取出最小的那个。整体来看是把这一组数分成两块,一块是一个除以3余1的数,另一块是可以被3整除的。

        下面的另外三种也是一样的分组方式。

        但是我们要注意,这些情况有可能不会全都有,因此我们可以先将x1 x2 y1 y2等赋值为

10010(题目中数组元素最大为10000),这样我们在最后取max的时候就必然不会取到无效情况。

 

更新最小值以及次小值只需要分类讨论即可 

 

class Solution {
public:
    int maxSumDivThree(vector<int>& nums) {
        int sum = 0;
        int n = nums.size();
        for(int i = 0; i < n; i++)
        {
            sum += nums[i];
        }
        if(sum % 3 == 0)
        {
            return sum;
        }
        else if(sum % 3 == 1)
        {
            int x1,y1,y2;
            x1 = y1 = y2 = 1e4 + 10;
            for(int i = 0; i < n; i++)
            {
                int tmp = nums[i];
                if(tmp % 3 == 1)
                {
                    x1 = min(x1, tmp);
                }
                else if(tmp % 3 == 2)
                {
                    if(tmp <= y1)
                    {
                        y2 = y1;
                        y1 = tmp;
                    }
                    else if(tmp > y1 && tmp <= y2)
                    {
                        y2 = tmp;
                    }
                }
            }
            return max(sum - x1, sum - y1 - y2);
        }
        else//取余等于2
        {
            int x1,x2,y1;
            x1 = x2 = y1 = 1e4 + 10;
            for(int i = 0; i < n; i++)
            {
                int tmp = nums[i];
                if(tmp % 3 == 2)
                {
                    y1 = min(y1, tmp);
                }
                else if(tmp % 3 == 1)
                {
                    if(tmp <= x1)
                    {
                        x2 = x1;
                        x1 = tmp;
                    }
                    else if(tmp > x1 && tmp <= x2)
                    {
                        x2 = tmp;
                    }
                }
            }
        return max(sum - x1 - x2, sum - y1);
        }
    }
};

 

class Solution {
public:
    int maxSumDivThree(vector<int>& nums) {
        int sum = 0;
        int n = nums.size();
        for(int i = 0; i < n; i++)
        {
            sum += nums[i];
        }
        if(sum % 3 == 0)
        {
            return sum;
        }
        else if(sum % 3 == 1)
        {
            int x1,y1,y2;
            x1 = y1 = y2 = 1e4 + 10;
            for(int i = 0; i < n; i++)
            {
                int tmp = nums[i];
                if(tmp % 3 == 1)
                {
                    x1 = min(x1, tmp);
                }
                else if(tmp % 3 == 2)
                {
                    if(tmp <= y1)
                    {
                        y2 = y1;
                        y1 = tmp;
                    }
                    else if(tmp > y1 && tmp <= y2)
                    {
                        y2 = tmp;
                    }
                }
            }
            return max(sum - x1, sum - y1 - y2);
        }
        else//取余等于2
        {
            int x1,x2,y1;
            x1 = x2 = y1 = 1e4 + 10;
            for(int i = 0; i < n; i++)
            {
                int tmp = nums[i];
                if(tmp % 3 == 2)
                {
                    y1 = min(y1, tmp);
                }
                else if(tmp % 3 == 1)
                {
                    if(tmp <= x1)
                    {
                        x2 = x1;
                        x1 = tmp;
                    }
                    else if(tmp > x1 && tmp <= x2)
                    {
                        x2 = tmp;
                    }
                }
            }
        return max(sum - x1 - x2, sum - y1);
        }
    }
};

 9.距离相等的条形码

 1054. 距离相等的条形码 - 力扣(LeetCode)

 

如果出现最多的数超过(n+1)/2,那么必定有两个相同元素会相邻 

 

我们只需要把最大的那个元素先排好,然后去排其它的即可,我们的i如果越界,那么将其置为1即可 

class Solution {
public:
    vector<int> rearrangeBarcodes(vector<int>& barcodes) {
        int maxval = -1; 
        int maxcount = 0;
        unordered_map<int, int> hash;
        for(auto ch : barcodes )
        {
            if( maxcount < ++hash[ch] )
            {
                maxval = ch;
                maxcount = hash[ch];
            }
        }
        int n = barcodes.size();
        int i;
        vector<int> ret(n);
        for(i = 0; i < n && maxcount > 0; i += 2)
        {
            ret[i] = maxval;
            maxcount --;
        }
        hash.erase(maxval);
        for(auto& [x, y] : hash)
        {
            for(int j = 0; j < y; j++)
            {
                if(i >= n)i = 1;
                ret[i] = x;
                i += 2;
            }
        }
        return ret;
    }
};

 10.重构字符串

767. 重构字符串 - 力扣(LeetCode) 

        这道题和上一道题是一模一样的的,唯一的不同就是这道题可能无解,因此我们需要判断一些maxcount 会不会大于(s.size() + 1)/2. 

class Solution {
public:
    string reorganizeString(string s) {
        int n = s.size();
        char maxval;
        int maxcount = 0;
        string ret = s;
        unordered_map<char, int> hash;
        for(auto ch: s)
        {
            if(maxcount < ++hash[ch])
            {
                maxval = ch;
                maxcount = hash[ch];
            }
        }
        if(maxcount > (n + 1) / 2)return "";
        int i;
        for(i = 0; i < n && maxcount > 0; i += 2)
        {
            ret[i] = maxval;
            maxcount--;
        }
        hash.erase(maxval);
        for(auto &[x, y] : hash)
        {
            for(int j = 0; j < y; j++)
            {
                if(i >= n)i = 1;
                ret[i] = x;
                i += 2;
            }
        }
        return ret;
    }
};

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2335661.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

空间信息可视化——WebGIS前端实例(二)

技术栈&#xff1a;原生HTML 源代码&#xff1a;CUGLin/WebGIS: This is a project of Spatial information visualization 5 水质情况实时监测预警系统 5.1 系统设计思想 水安全是涉及国家长治久安的大事。多年来&#xff0c;为相应国家战略&#xff0c;诸多地理信息领域的…

Vue3微前端架构全景解析:模块联邦与渐进式集成

一、微前端核心模式 1.1 主应用与微应用通讯机制 1.2 架构模式对比 维度iFrame方案Web Components模块联邦组合式微前端样式隔离完全隔离Shadow DOM构建时CSS作用域动态样式表通信复杂度困难(postMessage)自定义事件依赖共享Props传递依赖共享不共享按需加载自动共享显式声明…

多模态大语言模型arxiv论文略读(十九)

MLLMs-Augmented Visual-Language Representation Learning ➡️ 论文标题&#xff1a;MLLMs-Augmented Visual-Language Representation Learning ➡️ 论文作者&#xff1a;Yanqing Liu, Kai Wang, Wenqi Shao, Ping Luo, Yu Qiao, Mike Zheng Shou, Kaipeng Zhang, Yang Yo…

【蓝桥杯选拔赛真题101】Scratch吐丝的蜘蛛 第十五届蓝桥杯scratch图形化编程 少儿编程创意编程选拔赛真题解析

目录 scratch吐丝的蜘蛛 一、题目要求 1、准备工作 2、功能实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 四、程序编写 五、考点分析 六、推荐资料 1、scratch资料 2、python资料 3、C++资料 scratch吐丝的蜘蛛 第十五届青少年蓝桥杯s…

游戏引擎学习第221天:(实现多层次过场动画)

资产: intro_art.hha 已发布 在下载页面&#xff0c;你会看到一个新的艺术包。你将需要这个艺术包来进行接下来的开发工作。这个艺术包是由一位艺术家精心制作并打包成我们设计的格式&#xff0c;旨在将这些艺术资源直接应用到游戏中。它包含了许多我们会在接下来的直播中使用…

前端基础之《Vue(4)—响应式原理》

一、什么是响应式 1、响应式英文reactive 当你get/set一个变量时&#xff0c;你有办法可以“捕获到”这种行为。 2、一个普通对象和一个响应式对象对比 &#xff08;1&#xff09;普通对象 <script>// 这种普通对象不具备响应式var obj1 {a: 1,b: 2} </script>…

Go学习系列文章声明

本次学习是基于B站的视频&#xff0c;【Udemy高分热门付费课程】Golang&#xff1a;完整开发者指南&#xff08;基础知识和高级特性&#xff09;中英文字幕_哔哩哔哩_bilibili 本人会尝试输出视频中的内容&#xff0c;如有错误欢迎指出 next page: Go installation process

Go:程序结构

文章目录 名称声明变量短变量声明指针new 函数变量的生命周期 赋值多重赋值可赋值性 类型声明包和文件导入包初始化 作用域 名称 命名规则&#xff1a; 通用规则&#xff1a;函数、变量、常量、类型、语句标签和包的名称&#xff0c;开头须是字母&#xff08;Unicode 字符 &a…

Python 二分查找(bisect):排序数据的高效检索

二分查找&#xff1a;排序数据的高效检索 第二天清晨&#xff0c;李明早早来到了图书馆。今天他的研究目标是bisect模块&#xff0c;特别是其中的bisect_left和bisect_right函数。这些函数实现了二分查找算法&#xff0c;用于在已排序的序列中高效地查找元素或确定插入位置。 …

【数据结构】堆排序详细图解

堆排序目录 1、什么是堆&#xff1f;1.1、什么是大顶堆1.2、什么是小顶堆 2、堆排序的过程3、堆排序的图解3.1、将数组映射成一个完全二叉树3.2、将数组转变为一个大顶堆3.3、开始进行堆排序 4、堆排序代码 1、什么是堆&#xff1f; 堆的定义&#xff1a;在一棵完全二叉树中&a…

CST1016.基于Spring Boot+Vue高校竞赛管理系统

计算机/JAVA毕业设计 【CST1016.基于Spring BootVue高校竞赛管理系统】 【项目介绍】 高校竞赛管理系统&#xff0c;基于 DeepSeek Spring AI Spring Boot Vue 实现&#xff0c;功能丰富、界面精美 【业务模块】 系统共有两类用户&#xff0c;分别是学生用户和管理员用户&a…

安卓性能调优之-掉帧测试

掉帧指的是某一帧没有在规定时间内完成渲染&#xff0c;导致 UI 画面不流畅&#xff0c;产生视觉上的卡顿、跳帧现象。 Android目标帧率&#xff1a; 一般情况下&#xff0c;Android设备的屏幕刷新率是60Hz&#xff0c;即每秒需要渲染60帧&#xff08;Frame Per Second, FPS&a…

GPT-SoVITS:5 步实现 AI 语音克隆

在 AI 技术高速迭代的今天&#xff0c;语音合成早已突破”机械朗读“的局限 —— 从短视频创作者的虚拟配音、游戏角色的个性化声线&#xff0c;到智能客服的自然交互&#xff0c;GPT-SoVITS正凭借其强大的多模态融合能力&#xff0c;成为实现”AI 声音克隆“与“情感化语音生成…

记录:安装 Docker Desktop 时直接设置安装路径及容器存储路径

近期学用 deepseek 本地知识库的构建&#xff0c;准备尝试几个不同的 RAG 工具&#xff0c;结果基本都需要 Docker 支持&#xff0c;故又重新拾起 Docker 来安装&#xff0c;刚好看到个不用目录链接就可以直接设置安装路径的方法&#xff0c;就记录一下&#xff0c;以免以后忘…

算法训练之贪心

♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨ 个…

Vagrant 安装指南:从零开始搭建开发环境

Vagrant 是一款强大的虚拟化工具&#xff0c;能够帮助开发者快速创建和管理轻量级的、可复制的开发环境。它通过与 VirtualBox、VMware 或 Hyper-V 等虚拟机提供程序结合使用&#xff0c;让你在本地轻松运行虚拟机。本文将详细介绍如何在 Windows、macOS 和 Linux 系统上安装 V…

APIGen-MT:高效生成多轮人机交互Agent数据的两阶段框架

APIGen-MT&#xff1a;高效生成多轮人机交互数据的两阶段框架 引言 随着人工智能技术的飞速发展&#xff0c;AI代理&#xff08;Agent&#xff09;已从简单的聊天机器人发展为能够执行复杂现实任务的系统&#xff0c;例如管理金融交易、安排预约和处理客户服务等。然而&#x…

【NLP】 21. Transformer整体流程概述 Encoder 与 Decoder架构对比

1. Transformer 整体流程概述 Transformer 模型的整个处理流程可以概括为从自注意力&#xff08;Self-Attention&#xff09;到多头注意力&#xff0c;再加上残差连接、层归一化、堆叠多层的结构。其核心思想是利用注意力机制对输入进行并行计算&#xff0c;从而避免传统 RNN …

《Vue Router实战教程》21.扩展 RouterLink

欢迎观看《Vue Router 实战&#xff08;第4版&#xff09;》视频课程 扩展 RouterLink RouterLink 组件提供了足够的 props 来满足大多数基本应用程序的需求&#xff0c;但它并未尝试涵盖所有可能的用例&#xff0c;在某些高级情况下&#xff0c;你可能会发现自己使用了 v-sl…

开发一个答题pk小程序的大致成本是多少

答题 PK 小程序通常指的是一种允许用户之间进行实时或异步答题竞赛的应用程序&#xff0c;可能结合PK答题、积分系统、排行榜等功能。 一、首先&#xff0c;确定答题 PK 小程序的基本功能模块。这可能包括用户注册登录、题库管理、题目类型&#xff08;单选、多选、判断等&am…