一、基础数据结构——1.链表——2.静态链表

参考资料:《算法竞赛》,罗勇军 郭卫斌 著

本博客作为阅读本书的学习笔记,仅供交流学习。

建议关注 罗勇军老师博客

约瑟夫问题(洛谷 P1996)

题目描述

n n n 个人围成一圈,从第一个人开始报数,数到 m m m 的人出列,再由下一个人重新从 1 1 1 开始报数,数到 m m m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。

注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰 n − 1 n-1 n−1 名小朋友,而该题是全部出圈。

输入格式

输入两个整数 n , m n,m n,m。

输出格式

输出一行 n n n 个整数,按顺序输出每个出圈人的编号。

样例 #1

样例输入 #1

复制代码
10 3

样例输出 #1

复制代码
3 6 9 2 7 1 8 5 10 4

提示

1 ≤ m , n ≤ 100 1 \le m, n \le 100 1≤m,n≤100

1.1.2 静态链表

使用预先分配的一段连续空间存储链表,具体有两种做法:

  1. 使用结构体数组实现
  2. 使用一维数组实现
1. 使用结构体数组实现
  • 有些测评环境的栈空间很小,大数组定义在局部会占用栈空间
  • 有些编译器中,大静态数组定义在函数内部会出错
    因而,用结构体数组实现静态链表,静态分配应该定义在全局。
    ① 单向静态链表
cpp 复制代码
#include <bits/stdc++.h>
const int N = 105;
struct node{
    int id,nextid;
    //int data; //根据具体情况定义数据data
}nodes[N];

int main() {
    int n,m;
    scanf("%d %d",&n,&m);
    nodes[0].nextid = 1;
    for (int i = 0; i <= n; ++i) {
        nodes[i].id = i;
        nodes[i].nextid = i+1;
    }
    nodes[n].nextid = 1;
    int now = 1, prev = 1;
    while((n--)>1){
        for (int i = 1; i < m; ++i) {
            prev = now;
            now = nodes[now].nextid;
        }
        printf("%d ",nodes[now].id);
        nodes[prev].nextid = nodes[now].nextid;
        now = nodes[prev].nextid;
    }
    printf("%d",nodes[now].nextid);
    return 0;
}

② 双向静态链表

cpp 复制代码
#include <bits/stdc++.h>
const int N = 105;
struct node{
    int id,nextid,preid;
    //int data; //根据具体情况定义数据data
}nodes[N];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    nodes[0].nextid = 1;
    for (int i = 1; i <= n; ++i) {
        nodes[i].id = i;
        nodes[i].preid = i-1;
        nodes[i].nextid = i+1;
    }
    nodes[n].nextid = 1;
    nodes[1].preid = n;
    int now = 1;
    while((n--)>1){
        for (int i = 1; i < m; ++i)
            now = nodes[now].nextid;
        printf("%d ",nodes[now].id);
        int prev = nodes[now].preid;
        int next = nodes[now].nextid;
        nodes[prev].nextid = nodes[now].nextid;
        nodes[next].preid = nodes[now].preid;
        now = next;
    }
    printf("%d",nodes[now].nextid);
    return 0;
}
2. 使用一维数组实现

定义一个一维数组nodes[ ],其中nodes[ i ]的 i 就是结点的值,而nodes[ i ]的值是下一个结点。

优点:简单,书写方便

缺点:一个结点只能存放一个数据,扩展性差

cpp 复制代码
#include <bits/stdc++.h>
int nodes[150];
int main(){
    int n,m;
    scanf("%d %d",&n,&m);
    for (int i = 1; i <= n-1; ++i)
        nodes[i] = i+1;
    nodes[n] = 1;
    int now = 1, prev = 1;
    while((n--)>1){
        for (int i = 1; i < m; ++i) {
            prev = now;
            now = nodes[now];
        }
        printf("%d ",now);
        nodes[prev] = nodes[now];
        now = nodes[prev];
    }
    printf("%d",now);
    return 0;
}
相关推荐
8RTHT1 小时前
数据结构(三)---单向循环链表
数据结构·链表
张立龙6663 小时前
有序二叉树各种操作实现(数据结构C语言多文件编写)
c语言·开发语言·数据结构
Y.O.U..3 小时前
力扣HOT100——560.和为k的子数组
数据结构·c++·算法·leetcode
wuqingshun3141594 小时前
经典算法 判断一个图中是否有环
java·开发语言·数据结构·c++·算法·蓝桥杯·深度优先
柃歌4 小时前
【LeetCode Solutions】LeetCode 160 ~ 165 题解
数据结构·算法·leetcode
爱编码的傅同学4 小时前
数据结构(六)——红黑树及模拟实现
数据结构·算法
小黑屋的黑小子4 小时前
【数据结构】HashMap源码 —— 简单介绍
数据结构·算法·面试·源码·hashmap
猛踹瘸子那条好腿の4 小时前
使用Form.List且有Select组件
javascript·数据结构·antd
灋✘逞_兇6 小时前
快速幂+公共父节点
数据结构·c++·算法·leetcode
十五年专注C++开发7 小时前
面试题:请描述一下你在项目中是如何进行性能优化的?针对哪些方面进行了优化,采取了哪些具体的措施?
开发语言·数据结构·c++·qt·设计模式·性能优化