洛谷--链表

约瑟夫问题

约瑟夫问题是一个链表的典型问题,为啥要用到链表呢?因为链表的优越性实在太多了~

首先,有一个叫"循环链表"的东西非常适合这道题目

比如样例n = 3,m=10的情况,我们可以建立一个的循环链表:

1->2->3->4->5->6->7->8->9->10

^                                               ^

|                                                |

<-   <-  <-  <-   <-  <-  <-   <-   <-  

第10个的下一个正好指向第1个,非常符合题目的设定

其次,链表的删除操作非常简便

如果要删掉数组中的一个元素,需要把它之后的所有元素都向前移一个单位,太麻烦了有木有?!而链表恰恰相反,删除数据的操作很简单,只需要改变他们建立的联系就行

什么意思呢?还是用样例解释:当第3个人出圈之前,他们的关系是这样的:

1 -> 2 -> 3 -> 4 ->5

而出圈之后,他们的关系就成了这样:

            -> ->

        |              |

  1->2    3  ->  4 ->5

也就是说,我们把第2个的下一个直接指向了第4个,从而跳过了第3个

用数组也可以模拟链表

我们可以定义一个数组,来存储每个元素的下一个元素

因为这个题的数据是1~n连续的,所以我们可以用数组的下标来代表数据的内容,比如nxt[1] = 就是指第1个人的下一个是第2个,以此类推,nxt[2] = 3,nxt[3] = 4...第10个 的下一个当然是第一个了

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int []arr = new int[n];
        for(int i = 0;i<n-1;i++){
            arr[i] = i+1;
        }
        arr[n-1] = 1;//最后一个的下一个是第一个,特殊处理

模拟出圈过程,比如第3个人出圈时,把2的下一个从3改为4,下次到这里从2就会直接到达4,从而跳过3

接下来的人物就是数m个,输出,删掉,再数m个,输出,删掉...一直重复n次,嵌套循环就能完美解决

我们定义一个变量p,类似于一个指针,一直重复m次p取下一个的操作,然后输出出圈人的位置,然后把出圈人的前一个人指向他的下下个来跳出圈就行了

那么问题来了,如何利用next数组访问下一个呢?

我们要访问的数组下标(也就是人的位置) 正式arr[下标]的值,也就是说 p = arr[p]

现在来看细节:最好不要让p到达出圈人的位置,因为出圈人的位置是要被跳过的,p留在这里很不方便

把p放在出圈人的前一个位置就可以,输出的话再输出p的下一个,然后把next[p] 改成next[next[p]]

除此之外,还有一个小问题 既然是把p放到出圈人的前一个位置,那么把p = next[p]执行(m-1)次,但第一个如果从1开始,执行(m-1)次还是到了出圈人的位置.

int p = n-1;//从最后一个人的前一个开始
        //建立p变量(类似指针)来遍历数组,初始化为0
        for(int i= 1;i<=n;i++){//n个人出圈n次
            for(int j = 1;j<m;j++){
                //移动(m-1)次,到达出圈人人的前一个位置
                p = arr[p];//p到达下一个
            }
            //此时p到达除权日的前一个位置
            System.out.print(arr[p]+1);//输出出圈人的位置 +1是因为我们数组下标从0开始的
            System.out.print(" ");
            arr[p] = arr[arr[p]];//把p指向p的下下个,跳过(删除出圈人)
        }

完整代码:

import java.util.Scanner;

public class yjy {
    public static void main(String[] args) {
        // 约瑟夫问题
        // -- 循环链表 --
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int []arr = new int[n];
        for(int i = 0;i<n-1;i++){// 0 1 2 3 4.. 9
            arr[i] = i+1;      //   1 2 3 4 5...0
        }
        arr[n-1] = 0;
        int p = n-1;
        for(int i = 0;i<n;i++){//n个人出列
            for(int j = 1;j<m;j++){//(m-1)
                p = arr[p];//下一个
            }
            //待删除点的前一个
            System.out.print(arr[p]+1+" ");
            //跳过这个点
            arr[p] = arr[arr[p]];
        }

    }
}

队列安排

手拉手的过程

#include <iostream>
#include<bits/stdc++.h>
using namespace std;

const int mx = 1e5 + 10;

struct Student {
    int left, right; // 每个同学的“左右手”
    bool removed;    // 表示同学是否被移除
} students[mx] = { 0 };

void add(int position, int id, int side) // 新增同学
{//position 参考同学
    if (side == 0) { // 左边
        students[id].right = position;
        students[id].left = students[position].left;
        students[students[position].left].right = id;
        students[position].left = id;
    }
    else { // 右边
        students[id].left = position;
        students[id].right = students[position].right;
        students[students[position].right].left = id;
        students[position].right = id;
    }
}

int main() {
    int n, m;
    cin >> n;

    // 初始化
    students[0].right = 1; students[0].left = 1;
    students[1].left = 0; students[1].right = 0;
    students[1].removed = false;

    // 依次插入同学
    for (int i = 2; i <= n; ++i) {
        int position, side;
        cin >> position >> side;
        add(position, i, side);
        students[i].removed = false;
    }

    // 读取需要移除的同学编号并标记
    cin >> m;
    for (int i = 0; i < m; ++i) {
        int id;
        cin >> id;
        students[id].removed = true; // 将该同学标记为移除
    }

    // 输出结果
    for (int i = students[0].right; i != 0; i = students[i].right) {
        if (!students[i].removed) // 输出未标记的
            cout << i << " ";
    }
    cout << endl;

    return 0;
}

 

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

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

相关文章

SpringCloud整合Seata简易使用(注册中心Nacos)

SpringCloud整合Seata解决分布式事务&#xff08;注册中心Nacos&#xff09; Seata下载与配置在Nacos中配置seata相关配置持久化为db时&#xff0c;需要提前在数据库中创建seata数据库&#xff0c;SpringCloud整合Seata服务GlobalTransactional注解使用 本案例是在windows中运行…

纯血鸿蒙实战开发—如何添加顶部tab页面

1.Tabs组件 Tabs组件的页面组成包含两个部分&#xff0c;分别是TabContent和TabBar。TabContent是内容页&#xff0c;TabBar是导航页签栏. 根据不同的导航类型&#xff0c;布局会有区别&#xff0c;可以分为底部导航、顶部导航、侧边导航&#xff0c;其导航栏分别位于底部、顶…

windows上安装MongoDB,springboot整合MongoDB

上一篇文章已经通过在Ubuntu上安装MongoDB详细介绍了MongoDB的各种命令用法。 Ubuntu上安装、使用MongoDB详细教程https://blog.csdn.net/heyl163_/article/details/133781878 这篇文章介绍一下在windows上安装MongoDB&#xff0c;并通过在springboot项目中使用MongoDB记录用户…

每天五分钟计算机视觉:基于KNN算法完成图片分类任务

本文重点 在数字化和智能化的时代,图片分类作为计算机视觉领域的重要任务之一,已经广泛应用于各种场景,如安防监控、医疗诊断、智能推荐等。传统的图片分类方法往往需要复杂的手工特征提取和繁琐的分类器设计,而机器学习算法的引入为图片分类带来了不同的思路。 KNN算法概…

无人机航迹规划:人工原生动物优化器(Artificial Protozoa Optimizer ,APO)求解无人机路径规划,提供MATLAB代码

一、无人机模型介绍 单个无人机三维路径规划问题及其建模_无人机路径规划场景建模-CSDN博客 参考文献&#xff1a; [1]胡观凯,钟建华,李永正,黎万洪.基于IPSO-GA算法的无人机三维路径规划[J].现代电子技术,2023,46(07):115-120 二、人工原生动物优化算法APO求解无人机路径规…

什么台灯对眼睛好?一文给你分享具体什么台灯对眼睛好!

什么台灯对眼睛好&#xff1f;随着学生们最近陆续返校&#xff0c;家长们和孩子们都忙于开学初的准备工作&#xff0c;而眼睛的健康自然也是他们考虑的一部分。这也是护眼台灯在近年来变得非常普及的原因之一。我自己一直是一个近视的人&#xff0c;而且日常用眼时间也相当长。…

神经网络与深度学习——第15章 序列生成模型

本文讨论的内容参考自《神经网络与深度学习》https://nndl.github.io/ 第15章 序列生成模型&#xff0c;习题还没做先存在这里。 序列生成模型 序列概率模型 序列生成 N元统计模型 深度序列模型 模型结构 嵌入层 特征层 输出层 参数学习 评价方法 困惑度 BLEU算法 ROUGE算法 序…

「网络编程」基于 UDP 协议实现回显服务器

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;计网 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 实现回显服务器 &#x1f349;socket api&#x1f349;回显服务器&#x1f34c;实现&#x1f95d;服务器&#x1f95d;客户端 &#x1f3…

插入mysql报错:Incorrect string value: ‘\xF0\xAC\x8C\x97\xE5\x9E...‘

原因分析 这个错误通常发生在使用MySQL数据库时&#xff0c;尝试将包含四字节UTF-8字符&#xff08;通常表示为Unicode码点大于UFFFF的字符&#xff09;插入到一个不支持这种字符的字符集列中。一般在插入睡眠emoji表情时容易遇到 解决 -- 设置数据库编码utf8mb4 ALTER DAT…

伦敦金当前行情你真的看懂了吗?

5月中旬&#xff0c;伦敦金价将历史新高再次改写至2450美元/盎司&#xff0c;虽然随后两周出现了反复回落的走势&#xff0c;但整体的升浪仍然受到50天指数移动平均线的支撑。有分析机构预计&#xff0c;随着美联储美联储开始放缓缩表和开启降息周期&#xff0c;来年的伦敦金价…

Spring Boot自动配置原理和应用

我们知道&#xff0c;基于Spring Boot&#xff0c;我们只需要在类路径中引入一组第三方框架的starter组件&#xff0c;就能在Spring容器中使用这些框架所提供的各项功能。这在当下的开发过程中已经习以为常&#xff0c;但在Spring Boot还没有诞生之前却是不可想象的。如果我们使…

【Text2SQL 论文】QDecomp:探索 CoT-style 的 prompt 来解决 Text2SQL

论文&#xff1a;Exploring Chain of Thought Style Prompting for Text-to-SQL ⭐⭐⭐⭐ EMNLP 2023, arXiv:2305.14215 一、论文速读 本文通过对 LLM 使用 CoT-style 的 prompting 方法来解决 Text2SQL 问题&#xff0c;试图回答下面两个问题&#xff1a; 哪种 prompting s…

英伟达GPU架构加速狂飙

NVIDIA首席执行官黄仁勋在台湾大学体育馆发表主题演讲&#xff0c;展示了新一代Rubin架构&#xff0c;这是NVIDIA加速推出新架构的最新成果。 在讨论NVIDIA下一代架构时&#xff0c;黄仁勋提到了Blackwell Ultra GPU&#xff0c;并表示它可能会继续升级。然后他透露&#xff0c…

Zoom | saas企业分销裂变的典范

提到视频通讯&#xff0c;相信大家不会陌生&#xff0c;国外有Skype、Google meeting、Facetime&#xff0c;国内有腾讯会议、钉钉&#xff0c;为什么在如此众多竞争对手的情况下&#xff0c;Zoom能够一马当先&#xff0c;成为行业先锋&#xff1f; 一、公司简介 Zoom是集视频…

【电路笔记】-Sallen-Key滤波器

Sallen-Key滤波器 Sallen-Key 滤波器拓扑用作实现高阶有源滤波器的构建块。 1、概述 Sallen-Key 滤波器设计是一种二阶有源滤波器拓扑,我们可以将其用作实现高阶滤波器电路的基本构建块,例如低通 (LPF)、高通 (HPF) 和带通 ( BPF)滤波器电路。 正如我们在本滤波器部分中…

反激电源的类型与特点

主要分为 1 固定频率&#xff08;CCMDCM&#xff09; 2 可变频率控制&#xff08;CRM电流临界模式&#xff09; 这三种模式是很好辨别的&#xff0c;首先我们看左边的连续模式&#xff0c;Vds能看到他有一些尖峰毛刺&#xff0c;这是场效应管关闭的时候&#xff0c;LRC谐振导…

揭秘FL Studio21.2.8中文版一键解锁音乐创作新境界!

在音乐制作的广阔天地里&#xff0c;随着技术的不断进步和数字音频工作站&#xff08;DAW&#xff09;软件的普及&#xff0c;越来越多的音乐爱好者和专业制作人开始涉足音乐创作的奇妙旅程。其中&#xff0c;FL Studio以其强大的功能、直观的操作界面和丰富的音色资源&#xf…

用户管理的小demo--登录校检

目录 在user里面 装session 1、 LoginServlet.java 2、LoginFilter.java 3、配置路径 结果&#xff1a; 在user里面 装session 1、 LoginServlet.java package com.by.servlet;import com.by.pojo.User; import com.by.service.UserService; import com.by.service.impl…

云原生环境下GPU算力调度发展分析

云原生环境下GPU算力调度深度分析 概述&#xff1a; 云原生时代&#xff0c;GPU算力调度与管理备受瞩目&#xff0c;成为企业和云服务提供商关注的焦点&#xff0c;助力AI、深度学习、高性能计算等领域&#xff0c;满足对GPU资源的迫切需求。 容器化与编排&#xff1a; Kube…

LLM的基础模型4:初识Embeddings

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…