OpenJudge 2746(三种方法解决Joseph问题)

#include<stdio.h>

#include<string.h>

int vis[310];

void joseph(int n,int m)

{

    int i,j,k;

    int cnt=0,count=0;

    memset(vis,0,sizeof(vis));//0表示未选中

    for(i=1;count<n-1;i=i%n+1)//循环 n-1次 

    {

        if(vis[i]==0)

        {

           // vis[i]=1;

            cnt++;            

        }

        if(m==cnt)

        {

            vis[i]=1;//出圈 

            cnt=0;

            count++;

        }

    }

    for(j=1;j<=n;j++)

    if(vis[j]==0)

    {

        printf("%d\n",j);

        break;

    }

}   

int main()

/*

[Linker error] undefined reference to `WinMain@16' ,便是把main 写成了mian 

*/ 

{

    int m,n;

    while(scanf("%d%d",&n,&m),n||m)

        joseph(n,m);

    return 0;

}

 

 

/*

下面写递推公式:令f[i]表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n] 

递推公式  f[1]=0;  f[i]=(f[i-1]+m)%i; (i>1) 

因为实际生活中编号总是从1开始,我们输出f[n]+1  由于是逐级递推,不需要保存每个f[i]

*/ 

#include <stdio.h>  

#include<stdlib.h>

int main()  



{ 

    int n,m,i,s=0; 

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

    for(i=2; i<=n; i++) 

        s=(s+m)%i;  

    printf("The winner is %d\n", s+1); 

    system("pause");



} 











//尾插法带头结点的单向链表 

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

typedef struct Node

{

    int num;

    struct Node *next;

}Node;

int main()

{

    int i,j,n,m,count;

    Node *head,*p,*q;

    head=p=(Node *)malloc(sizeof(Node));

    while(scanf("%d%d",&n,&m),n||m)

    {

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

        {

            q=(Node *)malloc(sizeof(Node));

            q->num=i;

            p->next=q;

            p=p->next;

        }

        p->next=head;//构成循环链表 ,此时pq是一样的 

        j=0,count=0;

        for(p=head,q=p->next;count<n-1;)

        {

            j++;

            if(j==m)//删除 q结点 

            {

                p->next=q->next;

                free(q);

                q=p->next;//因为此时q已经释放,不能写成 q=q->next

                count++;//不能写在for内 

                j=0;   

            }

            else

            {

                p=p->next;

                q=p->next; 

            }

            if(q==head)//数到头结点则跳过去

            {

                p=p->next;

                q=q->next;

            }

            /*

            if(count==n-1) break;

            这句也可,不要for内的条件判定,但是不可放在第一个if内 ;

            因为需要经过第二个if

            */ 

        }

        printf("%d\n",q->num);//或者p->next->num,因为最后就剩两个节点,且p=head,q=head->next 

    }

    return 0;

} 

/*

若是多次输入,第一次结果正确,再次输入相同内容,结果不对

很可能是因为某些语句位置不正确,特别是带break的,(比如

printf语句中的变量在break语句之后还会有变化) 

*/ 

                

    





       

 

你可能感兴趣的:(open)