• 约瑟夫环


    问题描述:

    已知n个人围坐在一张圆桌周围,从编号为1的人开始报数,数到m的那个人出列。下一个人从1开始报数,数到m的人继续出列,以此类推直至全部人出列。求出列顺序?


    解决方案:

    1、最简单明了的办法就是用循环链表存储这n个人。数到m的人出列,只需将该结点从链表里剔除即可,然后继续往后报数,直到链表只剩下一个结点时结束。

    具体代码如下:

    typedef struct People
    {
    	int number;
    	People *next;
    }people;//////////////////////////////////////结点的存储结构
    
    void List_kind(People* L,int n,int m)
    {/////////////////////////////////////////////L为n个人构成的链表,报数报到m的人出列
    	People *q,*p=L;///////////////////////////p指向当前结点,q指向p的前驱
    	while(p->next != p)///////////////////////当链表只剩下一个结点,即报数剩下一个人的时候结束。
    	{
    		for(int i=1;i<m;i++)
    		{/////////////////////////////////////for循环实现功能:使p指向要出列的结点,q指向p的前驱
    			q=p;
    			p=p->next;
    		}
    		printf("%d
    ",p->number);
    		q->next=p->next;//////////////////////将要出列的结点从链表“剔除”
    		free(p);
    		p=q->next;////////////////////////////p指向出列的下一个结点,重新开始报数
    	}
    	printf("%d
    ",q->number);/////////////////输出最后一个人
    	free(q);
    }



    2、第二种办法就是用数组存储,难度将大大增加。但思路还是跟链表有点相似的。首先将要出列的元素输出,然后将它后面的所有元素都向前移一位,将已出列的元素填充掉。然后再向后找下一个要出列的元素。

    注意:当搜索到最后一个元素a[i]以后,用求余"%"功能,让数组和循环链表一样实现循环。另外,每次输出一个元素并把它填充掉以后,数组的总元素个数i会减一。

    具体代码如下:

    void Array_kind(int n,int m)
    {/////////////////////////////////////////////////////////n个人进行报数,报到m的出列
    	int *a,i,j,k;
    	a=(int*)malloc(sizeof(int));//////////////////////////为数组a动态分配内存
    	for(i=1;i<=n;i++)
    		a[i]=i;///////////////////////////////////////////对每个元素进行编号,代表每个人,注意编号从a[1]开始
    	for(i=n,k=1;i>=1;i--)/////////////////////////////////i为数组当前元素总个数
    	{
    		k=(k+m-1)%i;//////////////////////////////////////令k指向要出列的元素
    		if(k==0)//////////////////////////////////////////从上式知,当k+m-1=i时才会(k+m-1)%i=0。因为数组是从a[1]开始的,k=0时出列的元素应该是a[i],而不是a[0]。
    			k=i;
    		printf("%d
    ",a[k]);//////////////////////////////输出要出列的元素
    		for(j=k;j<i;j++)//////////////////////////////////k之后的元素都向前移一位,填充出列元素的位置。
    			a[j]=a[j+1];
    	}
    }

    理解代码最好的方式就是举具体的例子,我们假设n=7,m=3,求出列顺序,代码的实现如下:

    (下图表示第二个for循环的执行过程,每一行表示执行一次循环)










  • 相关阅读:
    app爬虫(python)开发——通过docker部署多任务端app应用数据抓取系统(终结篇)
    app爬虫(python)开发——app软件数据抓取进阶之实战笔记
    app爬虫(python)开发——简单app数据抓取入门实战案例笔记
    app爬虫(python)开发——移动端自动化控制工具(appium,inspector等)笔记
    JavaCV FFmpeg采集摄像头YUV数据
    java安全编码指南之:lock和同步的正确使用
    《.net之美》之读书笔记(二) C#中的泛型
    跟我一起学.NetCore之WebApi接口裸奔有风险(Jwt)
    一个爬虫的故事:这是人干的事儿?
    从零开始针对 .NET 应用的 DevOps 运营实践
  • 原文地址:https://www.cnblogs.com/Bone-ACE/p/4531309.html
Copyright © 2020-2023  润新知