首页 > 试题广场 >

约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3.

[问答题]
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。写程序实现上述过程。

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	int n;
	int m;
	int k;
	cin >> n >> m>>k;
	vector<int>inp(n);

	for (int i = 0; i < n; i++)
	{
		inp[i] = i+1;
	}

	int count = 0;
	int renshu = n;
	int cur = k-1;
	while (count < n - 1)//count==n-1时结束
	{
		if (cur + m > renshu)
		{
			if ((cur+m)%renshu == 0)
				cur=renshu-1;
			else
				cur = 0 + ((cur+m)%renshu) - 1;
		}
		else
			cur = cur + m-1;
		//cout << "cur=" << cur << '   ';
		renshu--;
		count++;
		//cout << "消除:";
		//cout << *(inp.begin() + cur) << endl;
		inp.erase(inp.begin() + cur);
	}
	cout << inp[0];
	return 0;
}

发表于 2017-08-11 11:17:04 回复(0)
#include<iostream>
#include<cstdio>
#include<queue>

using namespace std;

int main(){
    int n,k,m;
    while(scanf("%d%d%d",&n,&k,&m)){
        if(n==0 && k==0 && m==0){
            break;
        }
        queue<int>children;
        for(int i=1;i<=n;i++){    //依次加入队列
            children.push(i);
        }
        for(int i=1;i<k;i++){      //使编号为p的小孩站在队首  
            children.push(children.front());
            children.pop();
        }
        while(!children.empty()){
            for(int i=1;i<m;i++){    //使m-1个小孩依次重新入队
                children.push(children.front());
                children.pop();
            }
            if(children.size()==1){   //最后一个小孩的输出不同     
                printf("%d\n",children.front());
            }else{
                printf("%d,",children.front())''
            }
            children.pop();
        }
    }
    return 0;
}




发表于 2021-03-15 11:13:15 回复(1)
用STL队列实现循环队列

#include <iostream>
#include <queue>
using namespace std;
int main()
{
    int n,p,m;
    while(cin>>n>>p>>m)
    {
        if(n==0&&p==0&&m==0) break;
        queue<int> myQueue;
        for(int i=1;i<n+1;i++)
            myQueue.push(i);
        while(myQueue.front()!=p)
        {
            int i = myQueue.front();
            myQueue.pop();
            myQueue.push(i);
        }
        while(!myQueue.empty())
        {
            for(int i=0;i<m-1;i++)
            {
                int a = myQueue.front();
                myQueue.pop();
                myQueue.push(a);
            }
            if(myQueue.size()==1)
                cout<<myQueue.front()<<endl;
            else
                cout<<myQueue.front();
            myQueue.pop();
        }
    }
}

发表于 2022-03-01 20:35:17 回复(0)
#include<iostream>
#include<cstdio>
#include<queue>

using namespace std;

int main()
{
    int n,p,m;
    while(cin>>n>>p>>m){
        if(n==0&&p==0&&m==0) break;
        else{
            bool flag=true;
            queue<int> myqueue;
            for(int i=0;i<n;i++){
                myqueue.push(i+1);
            }
            for(int i=1;i<=p-1;i++){
                myqueue.push(myqueue.front());
                myqueue.pop();
            }
            while(!myqueue.empty()){
                for(int i=1;i<=m;i++){
                    if(i==m){
                        if(flag){
                            flag=false;
                        }
                        else{
                            cout<<",";
                        }
                        cout<<myqueue.front();
                        myqueue.pop();
                    }
                    else{
                        myqueue.push(myqueue.front());
                        myqueue.pop();
                    }
                }
            }
        }
                        printf("\n");
    }
    return 0;
}

发表于 2021-01-21 14:09:19 回复(0)
//    其实可以在把queue的队首元素弹出队列后
#include <iostream>
#
include <cstdio>
#include <queue>
using namespace std;

int main()
{
    int n,p,m;
    while(scanf("%d%d%d",&n,&p,&m)){
        if(n==0&&p==0&&m==0){
            break;
        }
        queue<int>children;
        for(int i=1;i<=n;++i){            //把1到n依次push进队列
            children.push(i);
        }
        for(int i=1;i<p;++i){                    //使编号为p的小孩在队首
            children.push(children.front());      //就要把p之前的小孩push进队列,从队头开始选取,再将队头原来的这个小孩pop掉
            children.pop();
        }
        while(!children.empty()){     //队列非空时
        for(int i=1;i<m;++i){         //从1报到m。那么,m之前的小孩,全部顺利通关,从队头出来,排回到队尾。这样的话,队头就是那个报数是m的小孩,至于怎么处理这个孩子呢?先printf再children.pop
            children.push(children.front());
            children.pop();
        }
        if(children.size()==1){              //最后一个小孩的输出不同
            printf("%d\n",children.front());
        }else{
            printf("%d,",children.front());
        }
        children.pop();
        }
    }
    return 0;
}

发表于 2020-03-05 19:10:35 回复(0)
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNextLine()) {
			int n = sc.nextInt();
			int k = sc.nextInt();
			int m = sc.nextInt();
			solve(n,k,m);
		}
	}
	
	public static void solve(int n, int k, int m) {
		Queue<Integer> queue = new LinkedList<Integer>();
		for(int i = 0; i < n; i++) {
			queue.offer(i+1);
		}
		for(int i = 0; i < k - 1; i++) {
			queue.offer(queue.poll());
		}
		while(!queue.isEmpty()) {
			for(int i = 0; i < m - 1; i++) {
				queue.offer(queue.poll());
			}
			int a = queue.poll();
			System.out.print(a);
		}
	}

}

发表于 2020-02-18 23:08:30 回复(0)
#include <iostream>
#include <cstdio>
#include <queue>

using namespace std;

int main(){
    int n, k, m;
    while(scanf("%d%d%d",&n, &k, &m)){
        if(n == 0 && k == 0&& m==0){
            break;
        }
        queue<int> children;
        for(int i=1;i<=n;++i){
            children.push(i);
        }
        for(int i=1;i<k;++i){
            children.push(children.front());
            children.pop();
        }
        while(!children.empty()){
            for(int i=1;i<m;++i){
                children.push(children.front());
                children.pop();
            }
            if(children.size() == 1){
                printf("%d\n", children.front());
            }else{
                printf("%d", children.front());
            }
            children.pop();
        }
    }
    return 0;
}

发表于 2020-01-28 23:44:24 回复(0)
public class Solution {
    public static int LastRemaining(int n,int m){
    	if(n<1||m<1)
    		return -1;
    	int last = 0;
    	for(int i=2;i<=n;i++)
    		last= (last+m)%i;
    	return last+1;
    }
    public static void main(String[] args) {
    	int out = LastRemaining(2,1);
    	System.out.println(out);
    }
 
}

发表于 2017-05-16 17:00:04 回复(0)
def josephus(n, k, m):
    people = list(range(1,n+1))
    i = k-1
    for num in range(n, 0, -1):
         i = (i+m-1)%num
         print people.pop(i)
    return 
josephus(10,2,7)

编辑于 2016-08-16 16:06:02 回复(0)
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
    int num;
    struct Node *next;
} LinkList;
LinkList *creat(int n)
{
    LinkList *p, *q, *head;
    int i = 1;
    p = (LinkList *)malloc(sizeof(LinkList));
    p->num = i;
    head = p;
    for (i = 2; i <= n; i++)
    {
        q = (LinkList *)malloc(sizeof(LinkList)); /*Malloc()向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。*/
        q->num = i;
        p->next = q;
        p = q;
    }
    p->next = head;        /*使链表尾指向链表头 形成循环链表*/
    return head;
}
void fun(LinkList *L, int m)
{
    int i;
    LinkList *p, *s, *q;
    p = L;
    printf("出列顺序为:");
    while (p->next != p)
    {
        for (i = 1; i < m; i++) /*从1开始*/
        {
            q = p;
            p = p->next;
        }
        printf("%5d", p->num);
        s = p;
        q->next = p->next;
        p = p->next; /*使p指向新的起点*/
        free(s);/*free()与malloc()函数配对使用,释放malloc函数申请的动态内存*/
    }
    printf("%5d\n", p->num);
}
int main()
{
    LinkList *L;
    int n, m;
    n = 9;
    m = 5;
    L = creat(n);
    fun(L, m);
    return 0;
}

发表于 2014-11-13 23:00:49 回复(0)