一、基础数据结构——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;
}
相关推荐
宁檬精7 小时前
算法练习——55.跳跃游戏
数据结构·算法·游戏
高山有多高10 小时前
顺序表:数据结构中的基础线性存储结构
数据结构
默默无名的大学生10 小时前
数据结构——链表的基本操作
数据结构·算法
_OP_CHEN10 小时前
数据结构(C语言篇):(十一)二叉树概念介绍
c语言·开发语言·数据结构·二叉树·学习笔记··
Neverfadeaway10 小时前
C语言————冒泡排序(例题2)
c语言·数据结构·算法·冒泡排序·升序排列·降序排列
散11210 小时前
01数据结构-B树
数据结构·b树
亦良Cool10 小时前
001-Pandas的数据结构
数据结构·pandas
nsjqj11 小时前
数据结构中的 二叉树
数据结构
初学小白...11 小时前
红黑树-数据结构
数据结构
captain37611 小时前
qqq数据结构补充
数据结构