约瑟夫环程序设计

  程序设计思想

  1.定义一个头指针。

   2.键盘输入一个数值控制链表的长度。

   3.利用输入的数值产生for循环结构输入结点位置的数据域,最后尾指针指向头节点,构成循环链表。

  4.输入报数的上限值,从头节点开始循环,报数的上限停下的结点被删除。

  5.从被删除的结点的下一个节点开始,以被删除的数据域为上限值继续循环。

  设计思想漏洞:  有开始删除的标志,没有结束标志。

遇到的问题

  1.循环的设置,从头循环结束。

  2.对于密码位置得到设定。

重写的程序设计思想

  1.建立一个包含位置与密码的数据域,再建立头指针。

  2.输入循环链表的长度,建立完好的循环链表。

  3.输入上限数,从头节点开始循环,在要删除的结点前一个节点停下。

  4.将下一个节点的密码设为上限数,输出下一个节点的位置。

  5.删除下一个节点,利用while循环判断上限数防止上限数是否过小可能导致循环停止。

  6.如果太小则将该节点的密码设置为上限数,输出位置,否则继续循环。

  7.再循环到只有一个节点的时候停止循环,循环外面直接输出最后一个节点的位置。

程序代码

#include <iostream>

using namespace std;

typedef struct

{

   int number; //结点的密码    

   int position; //结点的位置

}data;

typedef struct LNode

{

  data point;

  struct LNode *next;

}LNode,*Linklist;

int main()

{

  Linklist l;

  l=new LNode;

  l->next=NULL;

  Linklist r;

  r=new LNode;

  r=l;

  int n;    

  cout <<"请输入链表的长度:";

  cin>>n;

  cout <<"请输入"<<n<<"个整数:"<<endl;//链表的建立

  for(int i=1;i<=n;i++)     

  {

    Linklist p;

    p=new LNode;

    cin>>p->point.number;

    p->point.position=i;

    p->next=NULL;

    r->next=p;

    r=p;

    if(i==n)

    {

      p->next=l->next;

      cout <<p->next->point.number;

    }

  }

  int m;

  cout <<"请输入设定的上限数:";

  cin>>m;

  Linklist p;//验证是否可以循环输出,即循环链表是否建立成功

  p=new LNode;

  p=l->next;

  for(int i=1;i<=m;i++) //利用输出判定循环链表的建立

  {

  cout <<p->point.number<<p->point.position<<"  ";

  p=p->next;

  }

  cout <<endl;

  int t=0;//t代表执行的次数

  for(int i=1;i<=m;i++)//利用给出的上限数开始循环 依次输出密码的位置

  {

    p=p->next;

    if(i==m-1)

    {

      i=0;

      m=p->next->point.number;

      cout <<p->next->point.position<<"  ";

       t++;

      Linklist q;

      q=new LNode;

      q=p->next;

      p->next=q->next;

      delete q;

      while(m==1)    //防止密码太小导致循环停止

      {

        m=p->next->point.number;

        cout<<p->next->point.position<<"  ";

        t++;

        Linklist w;

        w=new LNode;

        w=p->next;

        p->next=w->next;

        delete w;

      }

    }

    if(t==n-1)   //判断是否只剩下一个结点,若剩下一个则结束循环

    {

      break;

     }

  }

  cout <<p->point.position<<endl;  //输出最后一个结点的位置

  return 0;

}

时间: 2024-10-31 21:49:37

约瑟夫环程序设计的相关文章

一个不简洁的约瑟夫环解法

约瑟夫环类似模型:已知有n个人,每次间隔k个人剔除一个,求最后一个剩余的. 此解法为变种,k最初为k-2,之后每次都加1. 例:n=5,k=3.从1开始,第一次间隔k-2=1,将3剔除,第二次间隔k-1=2,将1剔除.依此类推,直至剩余最后一个元素. 核心思路:将原列表复制多份横向展开,每次根据间隔获取被剔除的元素,同时将此元素存入一个剔除列表中.若被剔除元素不存在于剔除列表,则将其加入,若已存在,则顺势后移至从未加入剔除列表的元素,并将其加入.如此重复n-1次.面试遇到的题,当时只写了思路,没

ytu 1067: 顺序排号(约瑟夫环)

1067: 顺序排号Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 31  Solved: 16[Submit][Status][Web Board] Description 有n人围成一圈,顺序排号.从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位. Input 初始人数n Output 最后一人的初始编号 Sample Input 3 Sample Output 2 HINT Source freepro

约瑟夫环 C语言 单循环链表

/*---------约瑟夫环---------*/ /*---------问题描述---------*/ /*编号为1,2,-,n的n个人围坐一圈,每人持一个密码(正整数). 一开始任选一个正整数作为报数上限值m, 从第一个人开始自1开始顺序报数,报到m时停止. 报m的人出列,将他的密码作为新的m值,从他的下一个人开始重新从1报数, 如此下去,直至所有人全部出列为止.试设计一个程序求出列顺序.*/ /*---------问题分析---------*/ /*n个人围坐一圈,且不断有人出列,即频繁

循环单向链表(约瑟夫环)

#include <stdio.h> #include <stdlib.h> typedef struct List { int data; struct List *next; }List; //创建循环单向链表n为长度 List *list_create(int n) { List *head, *p; int i; head = (List *)malloc(sizeof(List)); p = head; p->data = 1; //创建第一个结点 for (i =

约瑟夫环问题

(约瑟夫环问题)有n个人围成一圈,顺序排号.从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那个人. package aiqiyi; import java.util.ArrayList; public class Main { public static int leftPerson(int n) { // 用list来保存n个人,序号为1~n ArrayList<Integer> list = new ArrayList<Integer>()

cdoj525-猴子选大王 (约瑟夫环)

http://acm.uestc.edu.cn/#/problem/show/525 猴子选大王 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 有m个猴子围成一圈,按顺时针编号,分别为1到m.现打算从中选出一个大王.经过协商,决定选大王的规则如下:从第一个开始顺时针报数,报到n的猴子出圈,紧接着从下一个又从1顺时针循环报数,...,如此下去,最后剩

约瑟夫环——POJ3379

题目描述: 给出一个长度是n的字符串环,每次搁k个加入字符串中对应位置的字母序的下一个字母,执行m次,问最后一次插入的是什么字母. 大致思路: 正着想的话只能用模拟的方法解决,但是m有10^9这么大,而把问题倒过来想一下的话,那就变成了给出一个n+m的字符串每次搁k个字符删掉一个,最后剩下一个长度为n的字符串,问起始位置是什么字母.这样的话就变成了约瑟夫问题,约瑟夫环问题可以在不用考虑内容的情况下计算出最后剩下元素的位置.又因为字符串是一个环,所以可以假定开始的位置就是1,最后操作结束的位置就是

约瑟夫环问题--递推解法

利用数学推导,如果能得出一个通式,就可以利用递归.循环等手段解决.下面给出推导的过程: (1)第一个被删除的数为 (m - 1) % n. (2)假设第二轮的开始数字为k,那么这n - 1个数构成的约瑟夫环为k, k + 1, k + 2, k +3, .....,k - 3, k - 2.做一个简单的映射. k         ----->  0              k+1    ------> 1              k+2    ------> 2           

poj 2886 Who Gets the Most Candies?(线段树+约瑟夫环+反素数)

Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 9934   Accepted: 3050 Case Time Limit: 2000MS Description N children are sitting in a circle to play a game. The children are numbered from 1 to N in clockwise o