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语句之后还会有变化) 
*/ 
                
    


       
原文地址:https://www.cnblogs.com/hxsyl/p/2617310.html