一、基础数据结构——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;
}
相关推荐
yuuki2332333 小时前
【数据结构】用顺序表实现通讯录
c语言·数据结构·后端
还是码字踏实4 小时前
基础数据结构之数组的双指针技巧之对撞指针(两端向中间):三数之和(LeetCode 15 中等题)
数据结构·算法·leetcode·双指针·对撞指针
抠脚学代码8 小时前
Linux开发-->驱动开发-->字符设备驱动框架
linux·数据结构·驱动开发
星释11 小时前
Rust 练习册 8:链表实现与所有权管理
开发语言·链表·rust
熬了夜的程序员11 小时前
【LeetCode】101. 对称二叉树
算法·leetcode·链表·职场和发展·矩阵
橘颂TA12 小时前
【剑斩OFFER】算法的暴力美学——串联所有单词的字串
数据结构·算法·c/c++
葵续浅笑12 小时前
LeetCode - 杨辉三角 / 二叉树的最大深度
java·数据结构·算法·leetcode
Miraitowa_cheems13 小时前
LeetCode算法日记 - Day 94: 最长的斐波那契子序列的长度
java·数据结构·算法·leetcode·深度优先·动态规划
.ZGR.14 小时前
第十六届蓝桥杯省赛 C 组——Java题解1(链表知识点)
java·算法·链表·蓝桥杯
Paxon Zhang16 小时前
数据结构之**二叉树**超全秘籍宝典2
java·数据结构·算法