约瑟环问题

例题:

       17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事,15个教徒和15个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法,30个人围成一个圆圈,从第一个人开始依次报数,每数到第九个人,就将他扔入大海,如此循环进行,直到仅剩余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。

 

解析:题目中30个人围成一圈,可以用一个循环的链来表示,使用结构数组来构成一个循环链。结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该人是否被扔下海的标记,为1表示还在船上。从第一个开始对还未扔下海的人进行计数,每数到9时,将结构中的标记改为0,表示该人已被扔下海了。这样循环计数,直到有15个人被扔下海为止。

还有一种办法:使用一个Boolean数组来模拟,非教徒站的位置为false,教徒站的位置为true。一开始,所有的位置都为true,每数到9时,则自动将true设为false,如果该位置已经为false,则设置下一个true位置为false,如果已经循环到底,则重新开始。

 


public class Solution {
    private  static class Node{
        int val;
        boolean flag;
        Node next;
        public Node(int val){
            this.val = val;
            this.flag = false;
        }
    }
    public int LastRemaining_Solution(int n, int m) {
        if(n==0||m==0)
            return -1;
        
        Node pHead = new Node(0);
        Node first = pHead;
        for(int i=1;i<n;i++){
            Node node = new Node(i);
            first.next = node;
            first = first.next;
        }
        first.next = pHead;
        
        for(int i=0;i<n-1;i++){
           int count =0;
           while(count<m-1){
               if(!pHead.flag){
                   count++;
                   pHead = pHead.next;
               }else{
                   pHead = pHead.next;
               } 
           }
           if(!pHead.flag){
               pHead.flag = true;
               while(pHead.flag){
                   pHead = pHead.next;
               }
           }else{
               while(pHead.flag){
                   pHead = pHead.next;
               }
                pHead.flag = true;
               while(pHead.flag){
                   pHead = pHead.next;
               }
           }
        }
        while(pHead.flag){
            pHead = pHead.next; 
        }
          return pHead.val;
    }
}

 

### C++ 实现约瑟问题的红蓝队伍版本 为了实现约瑟问题中的红蓝队伍版本,可以采用链表结构来模拟人员的排列以及移除过程。通过定义节点类 `Node` 来表示每个人员及其所属队伍颜色,并利用循单向链表构建初始的人圈。 ```cpp #include <iostream> using namespace std; struct Node { char color; // 'R' for red, 'B' for blue int id; Node* next; }; class JosephusCircle { private: Node *head, *tail; public: JosephusCircle(int N); ~JosephusCircle(); void arrangeTeams(char team[], int size); // 安排团队成员的颜色 void playGame(int stepSizeRed, int stepSizeBlue); // 游戏逻辑执行函数 }; JosephusCircle::JosephusCircle(int N) : head(nullptr), tail(nullptr){ if (N <= 0) return; for (int i = 1; i <= N; ++i) { Node* newNode = new Node{ '\0', i, nullptr }; if (!head) { head = tail = newNode; tail->next = head; } else { tail->next = newNode; tail = newNode; tail->next = head; } } } JosephusCircle::~JosephusCircle() { if (!head) return; Node* current = head; do { Node* temp = current; current = current->next; delete temp; } while(current != head); } void JosephusCircle::arrangeTeams(char team[], int size) { Node* p = head; for (int i = 0; i < size && p; ++i) { p->color = team[i]; p = p->next; } } void JosephusCircle::playGame(int stepSizeRed, int stepSizeBlue) { Node* prev = tail; Node* curr = head; while(head->next != head) { if(curr->color == 'R') { for(int steps = 1; steps < stepSizeRed; ++steps) { prev = curr; curr = curr->next; } } else { // Blue Team for(int steps = 1; steps < stepSizeBlue; ++steps) { prev = curr; curr = curr->next; } } cout << "Person ID: " << curr->id << ", Color: " << curr->color << endl; prev->next = curr->next; delete curr; curr = prev->next; } } ``` 此代码实现了创建一个由指定数量个体组成的圆圈,并允许设置不同步长用于红色和蓝色队伍的游戏规则[^3]。游戏过程中会打印出局者的信息直至只剩余最后一名参与者为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值