【刷题汇总--游游的you、腐烂的苹果、孩子们的游戏(圆圈中最后剩下的数)】

news2024/11/26 15:42:00

C++日常刷题积累

  • 今日刷题汇总 - day005
    • 1、游游的you
      • 1.1、题目
      • 1.2、思路
      • 1.3、程序实现 - 蛮力法
      • 1.4、程序实现 - 贪心(优化)
    • 2、腐烂的苹果
      • 2.1、题目
      • 2.2、思路
      • 2.3、程序实现 - bfs
    • 3、孩子们的游戏(圆圈中最后剩下的数)
      • 3.1、题目
      • 3.2、思路
      • 3.3、程序实现 -- 环形链表
      • 3.4、程序实现 -- 约瑟夫环(动态规划法)
    • 4、题目链接

今日刷题汇总 - day005

1、游游的you

1.1、题目

在这里插入图片描述
在这里插入图片描述

1.2、思路

读完题知道,属于是贪心加模拟类的题型,那么肯定要满足you次数最多,再拼接oo满足最大分数的思想。其次,蛮力法我也写了,不过超出题目限制的空间范围了,思路就是按照题目模拟即可直接贴出来就不多说了。接下来,结合预处理方式,实现贪心的思路,既然我们需要you最大化,那么贪心的思想就是求you的最大次数,观察示例可知,you的次数是同时消耗a,b,c的次数,所以you的最大次数等于a,b,c中的最小值,其次,值得注意的是oo是1分,而ooo是2分,oooo是3分,可以推出oo的最大分数为b-1次数。然后,我们会先拼接you,会同时消耗b,那么oo最大分数就变成了b减去拼接you用掉o的次数,再-1即可。所以,最后的最大分数就等于you + oo的分数。接下来,具体看程序实现。

1.3、程序实现 - 蛮力法

就是模拟实现,过程略。

#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> y;
    stack<int> o;
    stack<int> u;
    int q = 0;
    int a = 0;
    int b = 0;
    int c = 0;
    cin >> q;
    while (q--) {
        cin >> a >> b >> c;
        while (a) {
            y.push(a--);
        }
        while (b) {
            o.push(b--);
        }
        while (c) {
            u.push(c--);
        }
        int you = 0;
        while (!y.empty() && !o.empty() && !u.empty()) {
            y.pop();
            o.pop();
            u.pop();
            you += 2;
        }
        while (!y.empty()) {
            y.pop();
        }
        int oo = 0;
        int m = 0;
        int flag = 0;
        while (!o.empty()) {
            flag = 1;
            o.pop();
            m++;
        }
        if (flag) oo = m - 1;
        else oo = m;
        while (!u.empty()) {
            u.pop();
        }
        cout << (you + oo) << endl;
    }
    return 0;
}

在这里插入图片描述

在这里插入图片描述

1.4、程序实现 - 贪心(优化)

首先,按照题目要求,编写输入q表示访问次数,也就是a,b,c的输入次数,那么采用预处理方法,输入一次处理一次。

#include <iostream>
using namespace std;

int main()
{
    int q = 0;
    cin >> q;
    int a,b,c;
    while(q--)
    {
        
    }
    return 0;
}

接着,处理a,b,c和you与oo的次数与分数的关系。定义变量you统计当前预处理的a,b,c中you的分数,通过上述思路分析思考得知,you的最大分数就等于a,b,c的最小次数乘以2(2表示的是它的分之),即:you最大分数 = 次数 X 分值即可。同理,思路中分析得知,oo具有b-1的性质,且you会消耗o的次数即b的次数,即:oo的最大分数,定义变量ooo = b - 1 - (you/2)即可。最后,输出每一次预处理的结果you + ooo即可。

#include <iostream>
using namespace std;

int main()
{
    int q = 0;
    cin >> q;
    int a,b,c;
    while(q--)
    {
        cin >> a >> b >> c;
        int you = min(a,min(b,c)) * 2;
        int ooo = max(b-(you/2)-1,0);
        cout << (you + ooo) << endl;
    }
    return 0;
}

在这里插入图片描述

2、腐烂的苹果

2.1、题目

在这里插入图片描述

2.2、思路

读完题,第一反应就是之前写过的dfs算法思路,再次理解题目要求,0,1,2分别表示空格、好苹果、坏苹果且是随机的(多个2,多个0,多个1),然后一样四个方向每分钟(理解为一次操作)进行传播(可以理解为搜索),然后求多少次传播操作后没有好苹果,或遍历完后传播不到的好苹果的情况返回-1即可。然后,再根据示例分析,这里适用dfs是不适用的,属于是一圈一圈的传播,而不是一个一个的,那么这里需要用到多源bfs思路。也就是需要满足同时一次操作对于多个坏苹果2进行它周围传播的情况,那么我们可以把同一次操作中所有的2坏苹果放进一个队列里,就可以实现每一次出队列就可同时操作多个2坏苹果,其次,每一次操作就是一次传播所以用一个变量count记录坏苹果传播的次数,但是注意的是外层传播时注意边界控制。然后,传播到空格0,不管,传播到1好苹果则,将1置为2或者标记为已传播(我这里才用标记),然后继续把这个被传播的好苹果标记后,进入坏苹果队列,继续排序传播即可。遍历传播结束后,最后再遍历二维数组判断是否还有1好苹果,则返回-1即可,否则输出count传播次数。
由于不好理解,我简单画个图,便于理解:
在这里插入图片描述
在这里插入图片描述
接下来,就是程序实现。

2.3、程序实现 - bfs

首先,按照采用bfs思路的需求,编写需要的方向数组dx和dy,定义m,n计算二维数组的大小方便执行遍历(访问)操作,其次,这里采用布尔类型数组vis标记法表示是否已传播,然后定义坏苹果队列badapple,这里pair<int,int>因为需要的下标所以是用pair存放坏苹果的行和列即可。然后,遍历二维数组将坏苹果进队列。

class Solution
{
    int m,n;
    int dx[4] = {0,0,1,-1};
    int dy[4] = {1,-1,0,0};
    bool vis[1001][1001] = {false};
    queue<pair<int,int>> badapple;

public:
    int rotApple(vector<vector<int> >& grid)
    {
        n = grid.size();
        m = grid[0].size();

        for(int i = 0;i < n;i++)
        {
            for(int j = 0;j<m;j++)
            {
                if(grid[i][j] == 2)
                    badapple.push({i,j});
            }
        }
};

接着,创建count计数传播次数,因为是相邻之间的传播所以可以利用传播次数就是输出结果。
然后,只要队列中有坏苹果则执行传播,即出一层坏苹果且用sz保存当前这一层有几个坏苹果,以便依次执行上下左右的传播操作,即有多少个坏苹果就执行多少次传播,实现模拟同时一层坏苹果的传播。然后if(x >=0 && x < n && y >=0 && y < m && grid[x][y] == 1 && !vis[x][y]),进行边界控制防止出界且为好苹果且未被标记,则将它标记为已传播,再将它进队列,成为理解的下一层将要传播得坏苹果之一,等待sz次后,完成所有得第二层坏苹果,依次类推,直到传播结束。

class Solution
{
    int m,n;
    int dx[4] = {0,0,1,-1};
    int dy[4] = {1,-1,0,0};
    bool vis[1001][1001] = {false};
    queue<pair<int,int>> badapple;

public:
    int rotApple(vector<vector<int> >& grid)
    {
        n = grid.size();
        m = grid[0].size();

        for(int i = 0;i < n;i++)
        {
            for(int j = 0;j<m;j++)
            {
                if(grid[i][j] == 2)
                    badapple.push({i,j});
            }
        }

        int count = 0;
        while(badapple.size())
        {
            count++;
            int sz = badapple.size();
            while(sz--)
            {
                auto [a,b] = badapple.front();
                badapple.pop();
                for(int k = 0; k < 4;k++)
                {
                    int x = a + dx[k];
                    int y = b + dy[k];
                    if(x >=0 && x < n && y >=0 && y < m && grid[x][y] == 1 && !vis[x][y])
                    {
                        vis[x][y] = true;
                        badapple.push({x,y});
                    }                  
                }
            }
        }
    }
};

传播结束有两种情况,要么当前层的所有坏苹果的下一次传播单元(数组下标)都是空格0,要么就是全部坏苹果被传播完毕(遍历完)。最后,只需要再次遍历这个二维数组判断是都还有未被感染的好苹果且为被标记,有则返回-1,否则就是输出count-1即可。

class Solution
{
    int m,n;
    int dx[4] = {0,0,1,-1};
    int dy[4] = {1,-1,0,0};
    bool vis[1001][1001] = {false};
    queue<pair<int,int>> badapple;

public:
    int rotApple(vector<vector<int> >& grid)
    {
        n = grid.size();
        m = grid[0].size();

        for(int i = 0;i < n;i++)
        {
            for(int j = 0;j<m;j++)
            {
                if(grid[i][j] == 2)
                    badapple.push({i,j});
            }
        }

        int count = 0;
        while(badapple.size())
        {
            count++;
            int sz = badapple.size();
            while(sz--)
            {
                auto [a,b] = badapple.front();
                badapple.pop();
                for(int k = 0; k < 4;k++)
                {
                    int x = a + dx[k];
                    int y = b + dy[k];
                    if(x >=0 && x < n && y >=0 && y < m && grid[x][y] == 1 && !vis[x][y])
                    {
                        vis[x][y] = true;
                        badapple.push({x,y});
                    }                  
                }
            }
        }

        for(int i = 0;i < n;i++)
        {
            for(int j = 0;j<m;j++)
            {
                if(grid[i][j] == 1 && !vis[i][j])
                    return -1;
            }
        }
        return count - 1;
    }
};

在这里插入图片描述

在这里插入图片描述

3、孩子们的游戏(圆圈中最后剩下的数)

3.1、题目

在这里插入图片描述

3.2、思路

读完题,立马知道了属于是之前写过的杨辉三角问题同样经典的约瑟夫环问题了。题目意思跟大家熟悉的数字炸弹游戏类似的规则,首先需要一个随机数m,然后这里是按照从0开始报数,让其后报数为m-3的小朋友退出,直到剩下最后一个小朋友即可。那么,对于约瑟夫问题可以采用蛮力法模拟实现,我这里就是使用环形链表来实现,其次还可以通过像利用杨辉三角的性质(状态方程)一样,结合约瑟夫环的规律递推(动态规划)求解。首先,链表方法,由于题目中已知小朋友的编号是有序的0~n-1,所以直接先让其进链表即可,然后判断m-1位置时,让其该位置释放掉即可,直到剩下最后一个小朋友的编号输出即可。值得注意的是需要处理一些细节等,如需要让被释放的位置的下一个位置作为计数的开始,所以需要一个it变量记录,变化的计数位置(可以巧妙的利用迭代器)。
然后,对于递推(动态规划法),跟之前写过的最小花费爬楼梯套路是一样的需要确定动态规划的状态表示以及状态转移方程。那么就来推理dp[i]和dp[n],为了方便理解画个图理解:
在这里插入图片描述

3.3、程序实现 – 环形链表

首先,我们建立链表,将编号插入链表。

class Solution {
  public:
    int LastRemaining_Solution(int n, int m)
    {
        list<int> lt;
        for (int i = 0; i < n; i++)
        {
            lt.push_back(i);
        }
    }
};

然后,我们利用迭代器变量it,记录按照规则走的位置,走到m-1位置处,直接用it.erase删除释放即可,值得注意的是,当调用 lt.erase(it) 删除元素后,返回的迭代器是指向被删除元素之后的那个元素的迭代器。因此,在删除元素后,不需要再手动将 it 设置为 lt.begin(),因为 it 已经自动更新为指向下一个元素的迭代器(如果存在的话)。所以,在删除元素后直接进行下一次循环即可。
另外,如果实现的循环呢?判断it遍历到end处就使它置begin位置即可。所以链表模拟相对于数组模拟,迭代器相对更好用。依次类推,遇见m-1就删除,直到链表中剩下一个编号,返回即可。

class Solution {
  public:
    int LastRemaining_Solution(int n, int m)
    {
        list<int> lt;
        for (int i = 0; i < n; i++)
        {
            lt.push_back(i);
        }
        auto it = lt.begin();
        while (lt.size() > 1)
        {
            for (int count = 1; count < m; ++count)
            {
                ++it;
                if (it == lt.end())
                {
                    it = lt.begin();
                }
            }
            it = lt.erase(it);
            if (it == lt.end())
                it = lt.begin();
        }
        return *it;
    }
};

在这里插入图片描述
在这里插入图片描述

3.4、程序实现 – 约瑟夫环(动态规划法)

接着,动态规划重要的在于分析和理解,状态表示以及状态转移方程,程序就相对简单了。
在这里插入图片描述
在这里插入图片描述
接着按照推导的方程写好程序即可。只需要说一下为什么这里%上的 i,其实就是推导出的dp[n] = (dp[n-1] + m)%n;只是把n换成每一次循环求的 i 而已,表示求每一步的映射关系。

class Solution {
public:
    int dp[5001];
    int LastRemaining_Solution(int n, int m)
    {
        dp[1] = 0;
        for(int i = 2;i <= n;i++)
            dp[i] = (dp[i-1] + m) % i;
        return dp[n];
    }
};

在这里插入图片描述

还可以进一步空间优化,直接控制变量即可。总结模拟就是老实的遍历删除,动态规划就是找规律,推导方程求解。

class Solution {
public:
    int LastRemaining_Solution(int n, int m)
    {
        int f = 0;
        for(int i = 2;i <= n;i++)
            f = (f + m) % i;
        return f;
    }
};

在这里插入图片描述
在这里插入图片描述

4、题目链接

游游的you
腐烂的苹果
孩子们的游戏(圆圈中最后剩下的数)

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

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

相关文章

桌面保存的Word文件删除怎么找回?超实用的三个方法?

在日常工作和学习中&#xff0c;我们经常会使用Word文档进行文字编辑和文件保存。但是&#xff0c;有时由于操作失误或系统故障&#xff0c;我们会不小心将存放在电脑桌面重要的Word文件删除了。导致无法挽回的损失&#xff0c;但幸运的是&#xff0c;有一些方法可以帮助我们找…

当火热的Mamba遇到火热的YOLO,会发生怎么样的反应吗?

作者&#xff1a;浙江师范大学 论文地址&#xff1a;https://arxiv.org/pdf/2406.05835 代码地址&#xff1a;https://github.com/HZAI-ZJNU/Mamba-YOLO 目录 前言一、摘要二、介绍二、相关工作2.1 实时目标检测器2.2 端到端的目标检测器2.3 视觉状态空间模型 三 方法3.1 基础知…

Victor CMS v1.0 SQL 注入漏洞(CVE-2022-26201)

前言 CVE-2022-26201 是 Victor CMS v1.0 中发现的一个 SQL 注入漏洞。该漏洞允许攻击者通过特制的 SQL 查询注入到应用程序中&#xff0c;从而访问或操作数据库中的数据。以下是详细信息&#xff1a; 漏洞描述&#xff1a; 类型&#xff1a;SQL 注入 (SQL Injection)影响版本…

第六篇——谋攻篇:上兵伐谋,不是说打仗要用计谋

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 战术层面的东西&#xff0c;即便战略对了&#xff0c;战术不对&#xff0…

二重积分 - 包括计算方法和可视化

二重积分 - 包括计算方法和可视化 flyfish 计算在矩形区域 R [ 0 , 1 ] [ 0 , 2 ] R [0, 1] \times [0, 2] R[0,1][0,2] 下&#xff0c;函数 z 8 x 6 y z 8x 6y z8x6y 的二重积分。这相当于计算曲面 z 8 x 6 y z 8x 6y z8x6y 与 xy 平面之间的体积。 二重积分…

劲爆!华为享界两款新车曝光,等等党有福了

文 | AUTO芯球 作者 | 雷慢 劲爆啊&#xff0c;北汽的一份环境影响分析报告&#xff0c; 不仅曝光了享界S9的生产进展&#xff0c; 还泄露了自家的另两款产品&#xff0c; 第一款是和享界S9同尺寸的旅行车&#xff0c; 我一看&#xff0c;这不是我最喜欢的“瓦罐”吗&…

20.【C语言】初识结构体(重要)

定义&#xff1a;由一批数据组合而成的结构型数据 作用&#xff1a;描述复杂对象&#xff0c;创建新的类型 格式&#xff1a; struct 对象 { …… } 介绍. 用法&#xff1a;结构体变量.成员变量 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> struct hotal…

达梦数据库的系统视图v$auditrecords

达梦数据库的系统视图v$auditrecords 在达梦数据库&#xff08;DM Database&#xff09;中&#xff0c;V$AUDITRECORDS 是专门用来存储和查询数据库审计记录的重要系统视图。这个视图提供了对所有审计事件的访问权限&#xff0c;包括操作类型、操作用户、时间戳、目标对象等信…

浅谈反射机制

1. 何为反射&#xff1f; 反射&#xff08;Reflection&#xff09;机制指的是程序在运行的时候能够获取自身的信息。具体来说&#xff0c;反射允许程序在运行时获取关于自己代码的各种信息。如果知道一个类的名称或者它的一个实例对象&#xff0c; 就能把这个类的所有方法和变…

亚马逊跟卖ERP的自动调价功能,能够简易地批量设置价格规则。

跟卖的智能调价 跟卖智能调价简单说是可以上调&#xff0c;下调就是怎么说&#xff1f;上调就是它根靠根据市场最低的价格情况进行去上调。 然后添加指定条件&#xff0c;到工具栏找到指定条件&#xff0c;点击添加指定条件。 然后选择店铺&#xff0c;比如选择店铺&#xf…

【C++】认识使用string类

【C】STL中的string类 C语言中的字符串标准库中的string类string类成员变量string类的常用接口说明成员函数string(constructor构造函数)~string(destructor析构函数)默认赋值运算符重载函数 遍历string下标[ ]迭代器范围for反向迭代器 capacitysizelengthmax_sizeresizecapaci…

软件测试之接口自动化测试实战(完整版)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 自从看到阿里云性能测试 PTS 接口测试开启免费公测&#xff0c;就想着跟大家分享交流一下如何实现…

Vue 前端修改页面标题无需重新打包即可生效

在public文件夹下创建config.js文件 index.html页面修改 其他页面的标题都可以用window.title来引用就可以了&#xff01;

力扣53. 最大子数组和(动态规划)

Problem: 53. 最大子数组和 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 1.定义dp数组&#xff1a;dp[i]表示以nums[i]为结尾的子序列的最大子序列和&#xff1b; 2.状态初始化&#xff1a;dp[0] nums[0],表示以nums[0]为结尾的子序列的最大子序列和为nums[0]…

自己动手实现语音识别

声音的本质是震动,震动的本质是位移关于时间的函数,波形文件(.wav)中记录了不同采样时刻的位移。 通过傅里叶变换,可以将时间域的声音函数分解为一系列不同频率的正弦函数的叠加,通过频率谱线的特殊分布,建立音频内容和文本的对应关系,以此作为模型训练的基础。 语音mfc…

面向对象案例:电影院

TOC 思路 代码 结构 具体代码 Movie.java public class Movie {//一共七个private int id;private String name;private double price;private double score;private String director;private String actors;private String info;//get和setpublic int getId() {return id;…

Nuxt3 的生命周期和钩子函数(十一)

title: Nuxt3 的生命周期和钩子函数&#xff08;十一&#xff09; date: 2024/7/5 updated: 2024/7/5 author: cmdragon excerpt: 摘要&#xff1a;本文详细介绍了Nuxt3中几个关键的生命周期钩子和它们的使用方法&#xff0c;包括webpack:done用于Webpack编译完成后执行操作…

Git-如何修改git项目的远程仓库地址

前言 因为工作需要&#xff0c;现在准备将原来的git项目远程仓库地址修改为另一个&#xff0c;那么需要如何做呢&#xff1f; 第一种 1、首先需要在github中新建一个repository 2、创建之后会有一个对应的远程仓库地址&#xff0c;复制这个新建repository的url备用 3、找…

ython 使用 cx_Freeze 打包,不想要打包文件中能直接看到依赖的代码,如何处理

背景&#xff1a;因为使用 cx_Freeze 打包时&#xff0c;添加需要依赖的文件 cx_Freeze 是一个用于将 Python 程序打包成独立可执行文件的工具&#xff0c;支持多个平台。当你需要打包包含多个 .py 文件的项目时&#xff0c;你可以通过编写一个 setup.py 文件来指定哪些模块应…

物联网平台产品介绍

中服云物联网平台在功能、性能、易用性方面有较大的提升&#xff0c;成为业界领先的工业物联网平台。主要包含8大能力&#xff1a;数据采集与控制、基础物联组件集、快速开发工具集、数据集管理、数据处理与分析、平台配置管理、手机端小程序、二次开发接口。 产品配图&#x…