题目描述

解法1:暴力解法

#include <iostream>

using namespace std;

int main()
{
    int n, m;
     m=2;
    scanf("%d", &n);
    bool vis[n];
    int t = 0, tot = n;
    while(tot > 0)//人数
    {
        int cnt = 0;
        while(1)
        {
            t++;
            if(t > n) t %= n;
            if(!vis[t]) cnt++;
            //printf("%d %d\n", vis[t], t);
            if(cnt == m) break;//数到m
        }
        //printf("%d\n", t);
        vis[t] = 1;
        tot--;
    }
    printf("%d\n", t);
    return 0;
}

解法2:使用数组解决

#include <stdio.h>
int main()
{
    //参数: n(人数),m(第m个人死),last(剩余的人数)
    int i,j,n,m,last;
    int tag[100];
    printf("输入参加的人数:\n");  
      scanf("%d",&n);  
      printf("输入每隔多少死一个人:\n");  
      scanf("%d",&m);
    printf("\n准备报数!\n\n");     
      //初始化数组
    for(i = 0;i < n;i++)
    {
        tag[i] = 1;    
     } 
      //开始报数
      j = 1;
      last = n;
      for(i = 0;last > 1;i++)
      {
        if(!tag[i%n])continue;
        if(j == m)
        {
            j = 1;
            tag[i%n] = 0;
            printf("第%d个人自杀了,大家快鼓掌!啪啪啪!\n",(i%n)+1);
            last--;
        }
        else j++;    
     } 
     for(i = 0;i < n;i++)if(tag[i])break;
     printf("第%d个人活下来了!\n",i+1);
     return 0;
}

解法3:使用链表解决

#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
struct node
{
    int data;
    node *next;
};
void out(node *&p1,node *&p2)
{
    p1->next = p2->next;
    free(p2);
}
node *Find(int k,node *p)
{
    int count = 0;
    node *p1,*p2;
    p1 = p;
    p2 = p->next;
    while(p2 != p1)
    {
        count++;
        if(count == k)
        {
            out(p1,p2);
            count = 0;
            p2 = p1->next;
        }
        else
        {
            p1 = p1->next;
            p2 = p2->next;
        }
    }
    return p2;
}

void get(node *&p)
{
    p = (node *)malloc(sizeof(node));
    p->next = NULL;
}
int main()
{
    node *p1,*p2,*s1,*s2;
    get(p1);
    s1 = p1;
    int n,k = 2;
    cin>>n;
    for(int i = 1;i <= n;i++)
    {
        get(p2);
        p1->next = p2;
        p2->data = i;
        p1 = p2;
    }
    p1->next = s1->next;

    cout<<Find(k,p1)->data<<endl;

}

解法4:使用数学公示

[info] 上面讲述的两种解决约瑟夫问题的方法都是模拟一个报数的流程,对付一些小的数据量 还可以,但是假如我们输入的数据量很大的时候,就会显得很笨重,我们需要使用一些 数学策略来解决这个问题,有这样一个递推公式: f1 =0; f[i]=(f[i-1]+m)%i; (i>1) 而我们根据上面这个递推公式,写出如下代码:

  #include <stdio.h>  

int main()  
{  
  int n, m, i, s=0;  
  printf ("N M = "); 
  scanf("%d%d", &n, &m);  
  for (i=2; i<=n; i++)s=(s+m)%i;  
  printf ("最后一个剩下的人: %d\n", s+1);  
  return 0;  
}

results matching ""

    No results matching ""