一、基础数据结构——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;
}
相关推荐
风筝在晴天搁浅15 分钟前
hot100 239.滑动窗口最大值
数据结构·算法·leetcode
夏乌_Wx27 分钟前
练题100天——DAY31:相对名次+数组拆分+重塑矩阵
数据结构·算法
LYFlied27 分钟前
【算法解题模板】-解二叉树相关算法题的技巧
前端·数据结构·算法·leetcode
爱学习的小仙女!1 小时前
算法效率的度量 时间复杂度 空间复杂度
数据结构·算法
Trouvaille ~2 小时前
【C++篇】把混沌映射成秩序:哈希表的底层哲学与实现之道
数据结构·c++·stl·哈希算法·散列表·面向对象·基础入门
Yeats_Liao2 小时前
MindSpore开发之路(四):核心数据结构Tensor
数据结构·人工智能·机器学习
菜鸟233号3 小时前
力扣78 子集 java实现
java·数据结构·算法·leetcode
Han.miracle3 小时前
数据结构与算法--008四数之和 与经典子数组 / 子串问题解析
数据结构·算法
AI科技星3 小时前
圆柱螺旋运动方程的一步步求导与实验数据验证
开发语言·数据结构·经验分享·线性代数·算法·数学建模
月明长歌3 小时前
【码道初阶】【Leetcode94&144&145】二叉树的前中后序遍历(非递归版):显式调用栈的优雅实现
java·数据结构·windows·算法·leetcode·二叉树