约瑟夫环 HOJ 1016

Java 源码解读
Java 集合类源码,JUC 源码解读
wangxiaoming

                                          HOJ 1016 Joseph's problem

题目链接:点击打开链接
约瑟夫环N个囚犯站成一圈, 准备杀掉, 从第1个人开始越过 k-2个人,杀掉第K个人,  然后越过 k -1                          个人杀掉 这个过程沿着一个圆圈进行 最后只剩下一个人。。。
          最后那个人可以活着。给定 N k 问最后那个人能活着
            这英文不好确实很头疼啊,好伤心的有木有啊

题目大意:
            每次看题都好费劲,要是我能读英文比北京晚报还溜就好了。。。 这里每次从0开始报数
            是说 约瑟夫的侄子, 每杀掉 第m  个人 ,例如: 每次杀掉 第 m个 人 假设  m = 2
0 1 2 3 4 5 6 7 8 9
                                                   假设 k  = m%n    第一轮之后 只剩下 n-1 个人 从 k 开始报数 1. 2..3.... 
                                         原队列编号:            k + 1, k+2 ..........n-2      n-1 ,    1  2 .....k-1
                                         从k开始报数编号:   1       2      3                    n-1-k  n-k  ,n+1-k
先按照约瑟夫环走一遍 假设一共有10 个人 每次杀掉第二个人
 代码:
#include<cstdio>
#include<cstdlib>

#define M 2
#define N 10
#define START 0

struct Linklist
{
    int data;
    struct  Linklist *next;
}LNode[N];

typedef struct Linklist *link;
 //定义节点
int main()
{
    link p, r;
    for(int i = 0 ; i < N ; i++)
    {
        LNode[i].data = i + 1;
        if(i < N-1)
        {
            LNode[i].next = &LNode[i+1];
        }
        else
        {//最后一个指向首位置
            LNode[i].next = LNode;
        }
    }
    p = &LNode[START]; //p指向首位置节点
    while(p->next != p)
    {
        //循环没有结束
        for(int i = 1 ; i < M ; i++)
        {//r 的作用就是用来记录最终节点盘p 在那个位置
            r = p ;
            p = p->next;
        }
        r->next  = p->next;
        printf("第%d个人杀掉\n", p->data);
        p = r->next;
        //上面以及已经结束了约瑟夫环
    }
   return 0;
}

结果很明显依次杀掉的人是 2 4 6 8 10 3 7 1 9
下面尝试其他方式进行求解:
数学归纳的思想:  每次删掉的是第 2 个人 那么 M = 2

所有最后剩下的就是    5 也就是说5 是幸存者
          
参考博客 :点击打开链接                       

。。。。。
                                                                               
初始:
1 2 3 4 5 6 7 8 9 10

 1、第一轮之后是:  从1 开始 2除掉   第一轮之后  
1   3 4 5 6 7 8 9  
  2、第二轮 从 3 开始数删掉的是4
1   3   5 6 7 8 9 10
3、第三轮 从6 开始 删掉的是6
1     5     7    8   9   10 
4、第四轮 从7 开始 删掉的是8
1       5    7    9  10
5、第五轮从9开始删掉10 


代码:
#include<iostream>
using namespace std;

int main()
{
    int m , n;
    int i ;
    int s = 0;
    cin>>n>>m;
    for(i = 2 ; i <= n ; i++)
    {
        s = (s + m)%i;
    }
    cout<<s+1<<endl;
    return 0;
}


代码:
#include<cstdio>

const int MAX = 32580;
const int MAX_NUM = 3520;

int main()
{//约瑟夫环问题
//问题描述 有n 个人做在一起
    //下面首先用线性塞子判断素数并进行标记
    bool prime[MAX] = { false };  //所有的数都设成false
    int p[MAX_NUM];    //用来存放素数的
    int n, i, j;
    int  k = 0;
    for(i = 2; i < MAX ; i++)
    {
       if(!prime[i])
           p[k++] = i;
       for(j = 0 ;j < k && i*p[j] < MAX; j++)
       {
           prime[i*p[j]] = true;
           if(i%p[j]== 0)
           {
               break;
           }
       }
       //至于上面的数字为什么要写成32580大概就是为了得到3520 个素数的

    }
    while(scanf("%d", &n) != EOF && n != 0)
    {
       //下面才是程序
       int m = 0 ;
       for(i = n-2 ; i >= 0 ; i--)
       {
           m = (m + p[i]) % (n-i);
       }
       printf("%d\n", m+1);
    }

    return 0;
}



                   

再提供一种环都解决方法:

/**
 * 类说明
 * 
 * <pre>
 * Modify Information:
 * Author        Date          Description
 * ============ =========== ============================
 * DELL          2017年3月31日    Create this file
 * </pre>
 * 
 */

public class ListHasCycle {

    /**
     * @param args
     */
    public static boolean hasCycle(ListNode head) {
        /* 
         * 判断一个链表中是否有环 
         * 1. 快慢指针的方式
         *  1->2->3->4->5>6->7
         *          
         *           5<-8-<9-<
         *             5 6 7 8 9 5 再回到5 这个就是有环的  这个 环有一定规则的
         *             怎样判断出这个环  一个速度是另外速度的两倍就可以
         */
        if(head == null) return false;
        ListNode fast = head;
        ListNode slow = head;
        while((fast != null) && (fast.next != null) ){
              slow = slow.next;
              fast = fast.next.next;
              if(fast == slow){
                  return true;
              }
        }
        return false;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ListNode node1 = new ListNode(5);
        ListNode node2 = new ListNode(6);
        ListNode node3 = new ListNode(7);
        ListNode node4 = new ListNode(8);
        ListNode node5 = new ListNode(9);
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node1;
        boolean ans = hasCycle(node1);
        System.out.println(ans);
    }
}



wangxiaoming CSDN认证博客专家 架构 Spring Boot Redis
博客是很好的总结和记录工具,如果有问题,来不及回复,关注微信公众号:程序员开发者社区,获取我的联系方式,向我提问,也可以给我发送邮件,联系 1275801617@qq.com
©️2020 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值