,约摄夫环问题是一个蛮有趣的问题: 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。 这就是约摄夫环问题,下面我用数组两种方法来写关于这个问题。
首先先用简单的方法便于理解。
c源代码
方法一:
#include<stdio.h>
#include<stdlib.h>
#define allper 6 //这里以6人举例
#define out 3 //out表示数到3出去
int main()
{
int people[allper] = {0}, i = 0, count = 0, left = allper; //count用于计数,left用于表示剩下的人数
for(i = 0; i < allper; i++)
{
people[i] = i+1; //初始话数组,值代表人的序号
}
while(left >0)
{
for(i = 0; i < allper; i++)
{
if(people[i] != 0)
count++;
if(count == out)
{
printf("%d people is out\n",i+1);
people[i] = 0; //0表示该人以出去
left--;
count = 0;
}
}
}
retuen 0;
}
第一种方法呢,大家都会做可是呢 当人数很多的时候,在执行的时候程序效率会很低 那么可不可像链表一样每次出去一个人我觉吧这个人从我的数据组删除下次就不在数他那 答案明显是有的。
源代码
方法二:
#include<stdio.h>
#define allper 6
#define out 3
int main()
{
int next[allper], prev = 0, i = 0, count = 0, left = allper; //next表示下标i接下来的下标值,prev表示上一个人的下标
for(i = 0; i < allper ; i++)
{
next[i] = (i + 1)%allper ; //初始化,并且形成一个环
}
i = 0;
while(left > 0)
{
count++;
if(count == out)
{
printf("%d peoplr is out \n\n",i + 1);
next[prev] = next[i]; // 这里很关键,下一个人的要出去的人下一个人下标赋值给当前这个人 下次就会跳过已经出去人的下标
count = 0;
left--;
}
prev = i;
i = next[i];
}
return 0;
}
方法二程序的效率显然是很高的可以媲美链表,因为程序每一步都是有效的,而不是像第一方法 到了后面需要去一个一个的判断是否出去。可能讲得太凌乱了,好吧我自己整理整理去。。。