回 帖 发 新 帖 刷新版面

主题:[讨论]编写一算法解决约瑟夫问题

设有N个人为坐在圆桌周围,现从第S个人开始报数,数到第M个人出列,然后从出列的下一个人重新开始报数,数到第M个人又出列……如此重复直到所有的人全不出列为止,例如当N=8,M=4,S=1,得到的新序列为:4,8,5,2,1,3,7,6

回复列表 (共25个回复)

11 楼


6楼太帅了,程序完全正确啊,可惜用的是很一般的C语言的做的,我们老是要求我们用链表来做啊,拜托啦

12 楼


6楼太帅了,可是用链表应该怎么做呢?

13 楼

[quote]
6楼太帅了,程序完全正确啊,可惜用的是很一般的C语言的做的,我们老是要求我们用链表来做啊,拜托啦[/quote]
这是你的作业题???

1楼的程序没有问题啊,你怎么会得出那个结果的?

14 楼


我是一个字一个字敲进去的,调试的时候真的有问题啊

15 楼

一楼算法证明:
假设数到第p个数时遇到的数,和数到第x个数到遇到的数一样,且p - n < x < p,而且x % m != 0, 否则会被跳过和第个p数遇到的数肯定不一样,那么说明数了x个数之后再数一圈就数到了第p个数,而数一圈数过的数应该是n减去要跳过的数,因为已经数过了x个数,所以要跳过[x / m]个数( []表示取整数部分 ),所以x + n - [x / m] = p
问题转化为: p - n = x - [x / m]...(1),且 x % m != 0, p - n < x < p, 求解x
因为x % m != 0 => x / m - 1 < [x / m] < x / m 
             => x - x / m + 1 > x - [x / m] > x - x / m
             => [x - x / m + 1] >= x - [x / m] > [x - x / m]
             => [x - x / m] + 1 >= x - [x / m] > [x - x / m]
             => [x - x / m] + 1 >= x - [x / m] >= [x - x / m] + 1
             => [x - x / m] + 1 = x - [x / m]
( 代入(1)式 )=> p - n - 1 = [x - x / m] = [x * ( m - 1 ) / m] ... (2)
因为x % m !=0 且 ( m - 1 ) %  m != 0 => ( x * ( m - 1 ) ) % m != 0
由(2)式 => 0 < x * ( m - 1 ) - m * ( p - n - 1 ) <= m - 1
由左边: => m * ( p - n - 1 ) < x * ( m - 1 )
        => m * ( p - n - 1 ) / ( m - 1 ) < x 
        => [m * ( p - n - 1 ) / ( m - 1 )] < x
        => [m * ( p - n - 1 ) / ( m - 1 )] + 1 <= x ...(3)
由右边: => x * ( m - 1 ) - ( m - 1 ) <= m * ( p - n - 1 )
        => ( x - 1 ) * ( m - 1 ) <= m * ( p - n - 1 )
        => x - 1 <= m * ( p - n - 1 ) / ( m - 1 )
        => x - 1 <= [m * ( p - n - 1 ) / ( m - 1 )]
        => x <= m * ( p - n - 1 ) / ( m - 1 ) + 1 ...(4)
由(3),(4) => x = [m * ( p - n - 1 ) / ( m - 1 )] + 1
               = [ p - n - 1 + ( p - n - 1 ) / ( m - 1 )] + 1
               = p - n - 1 + [( p - n - 1 ) / ( m - 1 )] + 1
               = p - n + [( p - n - 1 ) / ( m - 1 )]
由于计算机算整数除法直接就取整了,所以递归时就写成
       p = p - n + ( p - n - 1 ) / ( m - 1 )

16 楼

楼主,不好意思,偶目前还没学到链表,过两天买了严蔚敏的数据结构才能给你解决,假如你不着急的话,还有,我的程序还能简化:

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
    int i,j,result, N, M, S;
    scanf("%d%d%d", &N, &M, &S);
    for ( i = 1; i <= N; ++i )
    {
        for ( j = 1, result = 0; j <= i; ++j )
            result = ( M + result - 1 ) % ( N + j - i ) + 1;
        result = ( result + S - 2 ) % N + 1;
        printf("%d\n", result );
    }
    system("pause");    
}

17 楼

我看了一点我的书的最后一章的链表知识,写了个约瑟夫环的链表解
因为还没系统学,可能很不规范,楼主将就看吧
#include <stdio.h>
#include <stdlib.h>

int main( void )
{
    int i, j, n, m, s;
    struct jos
    {
        int num;
        struct jos* next;
    };

    scanf( "%d%d%d", &n, &m, &s );

    struct jos round[n];   // 要是你的编译器不支持变长数组的话就用malloc
    struct jos* tmp = &round[s - 1];

    for ( i = 0; i < n - 1; ++i )
    {
        round[i].num = i + 1;
        round[i].next = &round[i + 1];
    }
    round[n - 1].num = n;
    round[n - 1].next = &round[0];
        
    for ( i = 0; i < n; ++i )
    {
        for ( j = 0; j < m - 2; ++j )
            tmp = tmp -> next;
   //因为tmp指向数数字1的节点,跳过m-2个,指向了要删除的节点的前一个节点
        printf( "%d\n", tmp -> next -> num );
        tmp -> next = tmp -> next -> next; //删除节点
        tmp = tmp -> next; //再次指向数数字1的节点
    }
    system( "pause" );
    return 0;
}

18 楼

#include<stdio.h>
#include<alloc.h>
typedef struct node
{
 elemtype data;
 struct node *next;
}Lnode;
typedef int elemtype;
Lnode *creat()
{
    Lnode *h,*p;
    elemtype y,x;
    h=(Lnode*)malloc(sizeof(Lnode));
    h->next=NULL;
    do
    {
     x=0;
     scanf("%d\n",&y);
     if(y<0)
     printf("error\n");
     else
    {p=(Lnode*)malloc(sizeof(Lnode));
     p->data=y;
      p->next=h->next;
      h->next=p;
     }
     x++;
    }while(x>y);
    return(h);
};

int main(void)
{
 int i, j,n,result,m,s;
 scanf("%d%d%d",&n,&m,&s);
 for(i=1;i<=n;++i)
{
  for(j=1,result=0;j<=i;++j)
   {
    result=(m+result)%(n+j-i);
    result=(0==result)?(n+j-i):result;}
    result=(result+s-1)%n;
    result=(result==0)?n:result;
    printf("%d\n",result);
 }
 system("pause");
}

19 楼


我写的链表,有点问题,但是我太笨了,找不出来,帮忙哈

20 楼

http://bpttc.blog.sohu.com/33526250.html

楼主看我blog里的模拟方法解约瑟夫环,里面有采用循环链表方法

刚刚重新写了一下,在devcpp里测试通过

我来回复

您尚未登录,请登录后再回复。点此登录或注册