Qt C++春晚刘谦魔术约瑟夫环问题的模拟程序

什么是约瑟夫环问题?

约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3。
分析:
(1)由于对于每个人只有死和活两种状态,因此可以用布尔型数组标记每个人的状态,可用true表示死,false表示活。
(2)开始时每个人都是活的,所以数组初值全部赋为false。
(3)模拟杀人过程,直到所有人都被杀死为止。

魔术

1、4张牌对折后撕开,就是8张,叠放在一起就是ABCDABCD。注意,ABCD四个数字是完全等价的。
2、根据名字字数,把顶上的牌放到下面,但怎么放都不会改变循环序列的相对位置。譬如2次,最后变成CDABCDAB;譬如3次,最后换成DABCDABC。但无论怎么操作,第4张和第8张牌都是一样的。
3、把顶上3张插到中间任意位置。这一步非常重要!因为操作完之后必然出现第1张和第8张牌是一样的!以名字两个字为例,可以写成BxxxxxxB(这里的x是其他和B不同的牌)。
4、拿掉顶上的牌放到一边,记为B。剩下的序列是xxxxxxB,一共7张牌。
5、南方人/北方人/不确定,分别拿顶上的1/2/3张牌插到中间,但是不会改变剩下7张牌是xxxxxxB的结果。
6、男生拿掉1张,女生拿掉2张。也就是男生剩下6张,女生剩下5张。分别是xxxxxB和xxxxB。
7、把最顶上的放到最底下,循环7次,男生和女生分别会是xxxxBx和xxBxx。
8、最后执行约瑟夫环过程!操作到最后只剩下1张。当牌数为6时(男生),剩下的就是第5张牌;当牌数为5时(女生),剩下的就是第3张牌。就是第4步拿掉的那张牌!

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1157e96989d6436ea8772e76b1130263.png

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

在这里插入图片描述

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

.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <vector>
#include "brand.h"
#include <QPushButton>
#include <QRadioButton>
#include <QLineEdit>
#include <QLayout>
#include <QStackedWidget>
#include <QSplitter>
#include <QButtonGroup>
class Step: public QWidget
{
public:
    Step(QWidget *parent = 0):QWidget(parent){
        QVBoxLayout* vbox = new QVBoxLayout(this);
        QHBoxLayout* hboxLabel = new QHBoxLayout;
        hboxChoose = new QHBoxLayout;
        QHBoxLayout* hboxBtn = new QHBoxLayout;
        label = new QLabel(this);
        hboxLabel->addStretch();
        hboxLabel->addWidget(label);
        hboxLabel->addStretch();
        hboxBtn->addStretch();
        vbox->addLayout(hboxLabel);
        vbox->addLayout(hboxChoose);
        vbox->addLayout(hboxBtn);
    }
    void SetText(QString text){
        label->setText(text);
    }

    QHBoxLayout* GetChooseLayout(){
        return hboxChoose;
    }
    virtual bool Check() {
        return true;
    }
private:
    QLabel* label;
    QHBoxLayout* hboxChoose;
};

class Start: public Step
{
public:
    Start(QWidget *parent = 0):Step(parent)
    {
        SetText("请输入四个数字、字母或汉字");
        edit = new QLineEdit(this);
        edit->setPlaceholderText("请输入四个数字、字母或汉字");
        GetChooseLayout()->addWidget(edit);
    }
    QString GetStr(){
        return edit->text();
    }
    bool Check() {
        return edit->text().size() == 4;
    }

private:
    QLineEdit* edit;
};

class First: public Step
{
public:
    First(QWidget *parent = 0):Step(parent)
    {
        SetText("4张牌对折后撕开");
    }
};

class Second: public Step
{
public:
    Second(QWidget *parent = 0):Step(parent)
    {
        SetText("请输入您的名字");
        edit = new QLineEdit(this);
        edit->setPlaceholderText("请输入您的名字");
        GetChooseLayout()->addWidget(edit);
    }
    int GetNumber(){
        return edit->text().size();
    }
    bool Check() {
        return edit->text().size() > 0;
    }
private:
    QLineEdit* edit;
};


class Third: public Step
{
public:
    Third(QWidget *parent = 0):Step(parent)
    {
        SetText("把顶上3张插到中间任意位置");
        radio = new QRadioButton("第一张后面",this);
        radio1 = new QRadioButton("第二张后面",this);
        radio2 = new QRadioButton("第三张后面",this);
        radio3 = new QRadioButton("第四张后面",this);
        GetChooseLayout()->addWidget(radio);
        GetChooseLayout()->addWidget(radio1);
        GetChooseLayout()->addWidget(radio2);
        GetChooseLayout()->addWidget(radio3);
        radio->setChecked(true);
    }
    int GetChoose(){
        if(radio->isChecked())
            return 1;
        if(radio1->isChecked())
            return 2;
        if(radio2->isChecked())
            return 3;
        if(radio3->isChecked())
            return 4;
        return 1;
    }
private:
    QRadioButton* radio;
    QRadioButton* radio1;
    QRadioButton* radio2;
    QRadioButton* radio3;
};

class Four: public Step
{
public:
    Four(QWidget *parent = 0):Step(parent)
    {
        SetText("拿掉顶上的牌放到一边");
    }
};

class Five: public Step
{
public:
    Five(QWidget *parent = 0):Step(parent)
    {
        SetText("南方人/北方人/不确定,分别拿顶上的1/2/3张牌插到中间");
        QVBoxLayout* vbox = new QVBoxLayout;
        QHBoxLayout* hbox = new QHBoxLayout;
        QHBoxLayout* hbox1 = new QHBoxLayout;
        QButtonGroup* group = new QButtonGroup(this);
        QButtonGroup* group1 = new QButtonGroup(this);
        radio = new QRadioButton("南方人",this);
        radio1 = new QRadioButton("北方人",this);
        radio2 = new QRadioButton("不确定",this);
        radio3 = new QRadioButton("第一张后面",this);
        radio4 = new QRadioButton("第二张后面",this);
        radio5 = new QRadioButton("第三张后面",this);
        hbox->addWidget(radio);
        hbox->addWidget(radio1);
        hbox->addWidget(radio2);
        hbox1->addWidget(radio3);
        hbox1->addWidget(radio4);
        hbox1->addWidget(radio5);
        group->addButton(radio);
        group->addButton(radio1);
        group->addButton(radio2);
        group1->addButton(radio3);
        group1->addButton(radio4);
        group1->addButton(radio5);
        vbox->addLayout(hbox);
        vbox->addLayout(hbox1);
        GetChooseLayout()->addLayout(vbox);
        radio2->setChecked(true);
        radio3->setChecked(true);
    }
    int GetChoose(){
        if(radio->isChecked())
            return 1;
        else if(radio1->isChecked())
            return 2;
        else if(radio2->isChecked())
            return 3;
        return 1;
    }
    int GetChoose1(){
        if(radio3->isChecked())
            return 1;
        else if(radio4->isChecked())
            return 2;
        else if(radio5->isChecked())
            return 3;
        return 1;
    }
private:
    QRadioButton* radio;
    QRadioButton* radio1;
    QRadioButton* radio2;
    QRadioButton* radio3;
    QRadioButton* radio4;
    QRadioButton* radio5;
};

class Six: public Step
{
public:
    Six(QWidget *parent = 0):Step(parent)
    {
        SetText("男生拿掉1张,女生拿掉2张");
        radio = new QRadioButton("男生",this);
        radio1 = new QRadioButton("女生",this);
        GetChooseLayout()->addWidget(radio);
        GetChooseLayout()->addWidget(radio1);
        radio->setChecked(true);
    }
    int GetChoose(){
        if(radio->isChecked())
            return 1;
        if(radio1->isChecked())
            return 2;
        return 1;
    }
private:
    QRadioButton* radio;
    QRadioButton* radio1;
};

class Seven: public Step
{
public:
    Seven(QWidget *parent = 0):Step(parent)
    {
        SetText("把最顶上的放到最底下,循环7次");
    }
};

class Last: public Step
{
public:
    Last(QWidget *parent = 0):Step(parent){
        SetText("好运留下来");
        flag = 1;
    }
    void Init(){
        SetText("好运留下来");
        flag = 1;
    }

    void ChangeText(){
        switch(flag){
            case 0:
                flag = 1;
                SetText("好运留下来");
                break;
            case 1:
                flag = 0;
                SetText("烦恼都丢掉");
                break;
            default:
                break;
        }

    }
    int GetFlag(){
        return flag;
    }

private:
    int flag;
};

class Widget : public QSplitter
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
private:
    void StartGetData();
    void FirstStep();
    void SecondStep();
    void ThridStep();
    void FourStep();
    void FiveStep();
    void SixStep();
    void SevenStep();
    void LastStep();

    void UpdateData();
protected slots:
    void OnClicked(bool);
private:
    std::vector<Brand*> m_vecBrand;
    QString m_firstCard;

    QLabel* label;
    QPushButton* btn;
    QStackedWidget* m_stackedWidget;

    bool bOver;
};

#endif // WIDGET_H

.cpp

#pragma execution_character_set("utf-8")
#include "widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QSplitter(parent)
{
    setOrientation(Qt::Vertical);
    label = new QLabel("qweqwe",this);
    QWidget* widget = new QWidget(this);
    m_stackedWidget = new QStackedWidget(this);
    addWidget(label);
    addWidget(widget);
    setStretchFactor(1,2);

    m_stackedWidget->addWidget(new Start);
    m_stackedWidget->addWidget(new First);
    m_stackedWidget->addWidget(new Second);
    m_stackedWidget->addWidget(new Third);
    m_stackedWidget->addWidget(new Four);
    m_stackedWidget->addWidget(new Five);
    m_stackedWidget->addWidget(new Six);
    m_stackedWidget->addWidget(new Seven);
    m_stackedWidget->addWidget(new Last);

    QHBoxLayout* hbox = new QHBoxLayout;
    QVBoxLayout* vbox = new QVBoxLayout;
    btn = new QPushButton("下一步",this);
    hbox->addStretch();
    hbox->addWidget(btn);
    vbox->addWidget(m_stackedWidget);
    vbox->addLayout(hbox);
    widget->setLayout(vbox);
    connect(btn, SIGNAL(clicked(bool)), this, SLOT(OnClicked(bool)));

    bOver = false;
}

Widget::~Widget()
{

}

void Widget::StartGetData()
{
    Start* start = (Start*)m_stackedWidget->widget(0);
    QString str = start->GetStr();
    for(int i=0; i<str.length(); i++){
        Brand* brand = new Brand(QString(str[i]));
        m_vecBrand.push_back(brand);
    }
}

void Widget::FirstStep()
{
    Start* start = (Start*)m_stackedWidget->widget(0);
    QString str = start->GetStr();
    for(int i=0; i<str.length(); i++){
        Brand* brand = new Brand(QString(str[i]));
        m_vecBrand.push_back(brand);
    }
}

void Widget::SecondStep()
{
    Second* second = (Second*)m_stackedWidget->widget(2);
    int number = second->GetNumber();
    for(int i=0; i<number; i++){
        Brand* brand = m_vecBrand[0];
        m_vecBrand.erase(m_vecBrand.begin());
        m_vecBrand.push_back(brand);
    }
}

void Widget::ThridStep()
{
    Third* third = (Third*)m_stackedWidget->widget(3);
    int number = third->GetChoose();

    Brand* brand = m_vecBrand[0];
    Brand* brand1 = m_vecBrand[1];
    Brand* brand2 = m_vecBrand[2];

    m_vecBrand.erase(m_vecBrand.begin());
    m_vecBrand.erase(m_vecBrand.begin());
    m_vecBrand.erase(m_vecBrand.begin());

    std::vector<Brand*> vecBrand;
    for(int i=0; i<m_vecBrand.size(); i++){
        vecBrand.push_back(m_vecBrand[i]);
        if(number == i + 1){
            vecBrand.push_back(brand);
            vecBrand.push_back(brand1);
            vecBrand.push_back(brand2);
        }
    }
    m_vecBrand = vecBrand;
}

void Widget::FourStep()
{
    m_firstCard = m_vecBrand[0]->GetStr();
    setWindowTitle("当前选择牌为:"+ m_firstCard);
    m_vecBrand.erase(m_vecBrand.begin());
}

void Widget::FiveStep()
{
    Five* five = (Five*)m_stackedWidget->widget(5);
    int number = five->GetChoose();
    int number1 = five->GetChoose1();

    std::vector<Brand*> vecBrand;
    switch (number) {
    case 1:
        vecBrand.push_back(m_vecBrand[0]);
        m_vecBrand.erase(m_vecBrand.begin());
        break;
    case 2:
        vecBrand.push_back(m_vecBrand[0]);
        vecBrand.push_back(m_vecBrand[1]);
        m_vecBrand.erase(m_vecBrand.begin());
        m_vecBrand.erase(m_vecBrand.begin());
        break;
     case 3:
        vecBrand.push_back(m_vecBrand[0]);
        vecBrand.push_back(m_vecBrand[1]);
        vecBrand.push_back(m_vecBrand[2]);
        m_vecBrand.erase(m_vecBrand.begin());
        m_vecBrand.erase(m_vecBrand.begin());
        m_vecBrand.erase(m_vecBrand.begin());
        break;
    default:
        break;
    }

    std::vector<Brand*> vecBrand1;
    for(int i=0; i<m_vecBrand.size(); i++){
        vecBrand1.push_back(m_vecBrand[i]);
        if(number1 == i + 1){
            vecBrand1.insert(vecBrand1.end(), vecBrand.begin(), vecBrand.end());
        }
    }
    m_vecBrand = vecBrand1;
}

void Widget::SixStep()
{
    Six* six = (Six*)m_stackedWidget->widget(5);
    int number = six->GetChoose();
    switch (number) {
    case 1:
        m_vecBrand.erase(m_vecBrand.begin());
        break;
    case 2:
        m_vecBrand.erase(m_vecBrand.begin());
        m_vecBrand.erase(m_vecBrand.begin());
        break;
    default:
        break;
    }
}

void Widget::SevenStep()
{
    for(int i=0; i<7; i++){
        Brand* brand = m_vecBrand[0];
        m_vecBrand.erase(m_vecBrand.begin());
        m_vecBrand.push_back(brand);
    }
}

void Widget::LastStep()
{
    Last* last = (Last*)m_stackedWidget->widget(8);
    int flag = last->GetFlag();
    switch (flag) {
    case 0:
        m_vecBrand.erase(m_vecBrand.begin());
        break;
    case 1:
        Brand* brand = m_vecBrand[0];
        m_vecBrand.erase(m_vecBrand.begin());
        m_vecBrand.push_back(brand);
        break;
    }

    last->ChangeText();
}

void Widget::UpdateData()
{
    QString str;
    for(int i=0; i<m_vecBrand.size(); i++){
        str+= m_vecBrand[i]->GetStr();
    }
    label->setText(str);
}

void Widget::OnClicked(bool)
{
    if(bOver){
        setWindowTitle("magic");
        Last* last = (Last*)m_stackedWidget->widget(8);
        last->Init();
        bOver = false;
        btn->setText("下一步");
        m_stackedWidget->setCurrentIndex(0);
        return;
    }

    Step* step = (Step*)m_stackedWidget->currentWidget();
    if(!step->Check())
        return;

    if(m_vecBrand.size() == 1){
        m_vecBrand.clear();
        Last* last = (Last*)m_stackedWidget->widget(8);
        last->SetText("之前的牌为:"+ m_firstCard+ " 对上否?");
        bOver = true;
        btn->setText("重新开始");
        return;
    }

    switch (m_stackedWidget->currentIndex()) {
    case 0://4张牌
        StartGetData();
        break;
    case 1://对折撕开
        FirstStep();
        break;
    case 2://根据名字字数,把顶上的牌放到下面
        SecondStep();
        break;
    case 3://把顶上3张插到中间任意位置
        ThridStep();
        break;
    case 4://拿掉顶上的牌放到一边
        FourStep();
        break;
    case 5://南方人/北方人/不确定,分别拿顶上的1/2/3张牌插到中间
        FiveStep();
        break;
    case 6://男生拿掉1张,女生拿掉2张
        SixStep();
        break;
    case 7://把最顶上的放到最底下,循环7次
        SevenStep();
        break;
    case 8://好运留下来 烦恼都丢掉
        LastStep();
        break;
    default:
        break;
    }
    UpdateData();

    if(m_stackedWidget->currentIndex() + 1 < m_stackedWidget->count())
        m_stackedWidget->setCurrentIndex(m_stackedWidget->currentIndex() + 1);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

tkinter做一个秒表

文章目录 需求和框架布局和主流程计时函数 需求和框架 本文试图实现一个简单的秒表&#xff0c;内容如下 这个软件非常简单&#xff0c;其UI元素只有一个文字标签外加三个按钮&#xff0c;这三个按钮的功能如下 点击Start按钮&#xff0c;开始进行计时&#xff0c;同时Start变…

已解决:IDEA中@Autowired自动注入MyBatis Mapper报红警告的几种解决方法

今天在使用 IDEA 使用 MyBatis 的时候遇到了这种情况&#xff1a; 可以看到 userMapper 下有个红色的波浪警告&#xff0c;虽然代码没有任何问题&#xff0c;能正常运行&#xff0c;但是这个红色警告在这里杵着确实让人很窝心。 于是我在网上找了找&#xff0c;最终明白了原因…

【鸿蒙系统学习笔记】状态管理

一、介绍 资料来自官网&#xff1a;文档中心 在声明式UI编程框架中&#xff0c;UI是程序状态的运行结果&#xff0c;用户构建了一个UI模型&#xff0c;其中应用的运行时的状态是参数。当参数改变时&#xff0c;UI作为返回结果&#xff0c;也将进行对应的改变。这些运行时的状…

电脑提醒待办事项:高效、快捷、更科学的方法

在这个快节奏的社会里&#xff0c;我常常感到时间不够用&#xff0c;仿佛一天24小时根本不够我分配。每天都有一大堆待办事项等着我&#xff0c;但总是有这样那样的事情让我分心&#xff0c;导致我经常忘记一些重要的任务。 每次当我想起那些被遗忘的待办事项时&#xff0c;都…

本地创建Git仓库

在 Windows 下&#xff0c;可以通过以下步骤在本地创建一个 并模拟远程Git 仓库。 1、在命令行中打开模拟远程Git 仓库目标文件夹&#xff1a; 打开命令提示符或 PowerShell。例如&#xff1a; 创建裸仓库&#xff08;模拟远程仓库&#xff09;&#xff1a;创建一个裸仓库&am…

亚马逊、沃尔玛、eBay等跨境平台自养号测评的风险和技术解析

亚马逊等平台延伸至世界各地&#xff0c;竞争激烈。许多卖家使用自养号测评来提高产品排名和销量。但自养号测评技术存在一定的技术局限性&#xff0c;很多卖家的账号因对自养号原理和底层环境搭建缺乏了解很多卖家的账号被关联封禁。本文将为您揭示自养号测评的风险&#xff0…

【小呆的力学笔记】弹塑性力学的初步认知四:简单应力状态下的应力应变关系

文章目录 2. 简单应力状态下的应力应变关系2.1 简单拉伸的应力应变关系2.2 真实应力应变关系2.3 应力-应变关系简化模型 2. 简单应力状态下的应力应变关系 我们在高中就学过&#xff0c;弹簧拉伸力和变形量成比例&#xff0c;对于一般的金属材料&#xff0c;在一定载荷以内这种…

Cadence Allegro PCB设计88问解析(三十三) 之 Allegro 中 Quick Reports的使用

一个学习信号完整性仿真的layout工程师 在进行PCB设计时&#xff0c;经常会查看一下整个PCB的基本信息&#xff0c;比如器件个数&#xff0c;网络数量、pin的数量。尤其在投板的时候还要查看下Dangling Lines、Dangling Vias等。还有其他的关于shape、via、走线、钻孔等等相关信…

顶顶通实时质检系统如何添加词库

文章目录 前言联系我们步骤1. 导入系统预置词库2. 手动添加词库 在实时质检时如何质检到词库 前言 本篇文章主要讲解顶顶通实时质检系统如何添加词库。 词库添加的方式&#xff1a; 导入系统预置词库手动添加词库 联系我们 有意向了解实时质检系统的用户&#xff0c;可以点击…

Photoshop 2023(Ps)下载安装及详细安装教程

Photoshop(Ps)的介绍 Adobe Photoshop&#xff0c;简称“PS”&#xff0c;是由AdobeSystems开发和发行的图像处理软件。Photoshop主要处理以像素所构成的数字图像。使用其众多的编修与绘图工具&#xff0c;可以有效地进行图片编辑和创造工作。PS有很多功能&#xff0c;在图像、…

grafana配置钉钉告警模版(一)

1、配置钉钉告警模版 创建钉钉告警模版&#xff0c;然后在创建钉钉告警时调用模版。 定义发送内容具体代码 my_text_alert_list 是模版名称后面再配置钉钉告警时需要调用。 {{/* 定义消息体片段 */}} {{ define "my_text_alert_list" }}{{ range . }}告警名称&…

术业有专攻!三防加固平板助力工业起飞

在日常使用中的商业电脑比较追求时效性&#xff0c;以市场定位做标准&#xff0c;内部元件只需满足一般要求就行&#xff0c;使用寿命比较短。而三防平板电脑是主要运用在复杂、恶劣的环境下所以在需求方面较高,需要保证产品在恶劣条件下正常使用&#xff0c;满足行业领域的需求…

springboot746旧物置换网站

springboot746旧物置换网站 获取源码——》公主号&#xff1a;计算机专业毕设大全

二维码钓鱼激增587%:用户陷入社交诈骗陷阱!

Check Point软件技术公司发布的新研究揭示了典型的QR码攻击&#xff0c;通过Check Point的实时网络威胁地图&#xff0c;在两周内发现了2万起QR码钓鱼和恶意软件攻击事件&#xff0c;突显了QR码在网络犯罪分子面前的脆弱性。 QR码是"Quick Response Code"&#xff08…

minio+nginx 集群快速搭建

文章目录 1、概要2、整体架构流程3、集群搭建3.1、服务器准备3.2、下载并安装3.3、minio集群配置3.4、minio.service配置3.5、启动 4、nginx 转发 1、概要 minIO 是一个开源的分布式对象存储服务&#xff0c;可用于构建高可用性和高扩展性的存储集群。 分布式架构&#xff1a;…

SpringSecurity + OAuth2 详解

SpringSecurity入门到精通 ************************************************************************** SpringSecurity 介绍 **************************************************************************一、入门1.简介与选择2.入门案例-默认的登录和登出接口3.登录经过了…

CSS SVG技术制作的复杂多层发光星形加载动画组件

<template><!-- 定义一个视图容器,用于展示加载动画 --><view class="loader"><svg viewBox="0 0 128 128" height="128" width="128" class="star"><defs><filter id="star-glow&q…

Windows下用CMake编译ITK及配置测试

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 ITK是什么&#xff1f; ITK&#xff08; Insight Segmentation and Registration Toolkit&#xff09;是美国国家卫生院下属的国…

MBD_入门篇_18_Simulink查表模块

18.Simulink查表模块 18.1 概述 LookUpTable&#xff0c;查表模块。比较常用的模块&#xff0c;参数较多&#xff0c;会复杂一点&#xff0c;比较重要的模块&#xff0c;一定掌握。 18.2 n-DLookUpTable N维查表模块 18.2.1 查表原理 通过有限的数据去得出相关的结果。比如我们…

Leo赠书活动-16期 名校毕业生教材

Leo赠书活动-16期 名校毕业生教材 ✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠…