Algorithm One Day One -- 约瑟夫环(丢手绢问题)

算法是编程的灵魂,是编程思想的精髓————Algorithm One Day One

/********************************************************************
created:2015年1月20日 23:06:46
author: Jackery
purpose: Joseph problem
*********************************************************************/
#include"stdafx.h"
#include<iostream>
using namespace std;

typedef struct _Node
{
	int data;
	struct _Node*next;
} node_t;

typedef struct _Linklist
{
	node_t*phead;
	node_t*ptail;
	int len;
}Linklist;
static node_t*GetNode(int i )//新建并初始化节点
{
	node_t*pNode;
	pNode=new node_t;
	if(!pNode)
	{
		cout <<"内存分配失败" <<endl;
		exit(-1);
	}
	pNode->data=i;
	pNode->next=NULL;
	return pNode;
	delete pNode;
}
void init_list(Linklist*plist)//用第一个节点初始化循环单链表
{
	node_t*p;
	p=GetNode(1);
	//printf("TheNewNodeis:%d\n",p->data);//****TEST****
	plist->phead=p;
	plist->ptail=p;
	p->next=plist->phead;
	plist->len=1;
}

//把其余数据添加到循环单链表中
static void Create_List(Linklist*plist,int n)
{
	int i=0;
	node_t*pNew;
	for(i=2;i<=n;i++)
	{
		pNew=GetNode(i);
		/********TEST********
		cout <<"The New Node is:" <<pNew->data << endl;
		********TEST********/
		plist->ptail->next=pNew;
		plist->ptail=pNew;
		pNew->next=plist->phead;
		plist->len++;
	}
}
//输出链表内容
// void Print_List(Linklist*plist)
// {
// 	node_t*pCur=plist->phead;
// 	do
// 	{
// 		cout << "The "<<  pCur->data <<"person."  <<endl;
// 		pCur=pCur->next;
// 	}while(pCur!=plist->phead);
// 	cout << "The length of the List "<< plist->len<< endl;;
// }

//Joseph function implement
void joseph(Linklist* plist,int m,int k)
{
	node_t *pPre=plist->ptail;
	node_t *pCur=plist->phead;
	int i,j;
cout << "出队列的顺序依次为: "<< endl;
	while(plist->len != 1)
	{
		i=0;
		j=0;
		while(j<k-1)
		{
			pPre=pPre->next;
			j++;
		}
		while(i< m -1)
		{
			pPre=pPre->next;
			i++;
		}
		pCur=pPre->next;
		int temp=pCur->data;
	    cout <<"第 " << temp << "  个人 "<< endl ;
		pPre->next=pCur->next;
		free(pCur);
		plist->len--;
	}
	cout <<"第 " << pPre->data << " 个人" << endl; ;
	cout << "The last one is:" << pPre->data<< endl;
}
int main(int argc, char * argv[])
{
	int n=0;
	cout <<"约瑟夫环长度为 : "<<endl;;
	cin >> n;
	int m=0;
	cout << "每此数到m个时,此人出列"<<endl;
	int k;
    cin >> k;
	cout << "从第k 个开始数" << endl;
	cin >>m;
	Linklist pList;
	init_list(&pList);
	Create_List(&pList,n);
//	Print_List(&pList);
	joseph(&pList,m,k);
	return 0;
}





时间: 2024-07-31 21:57:10

Algorithm One Day One -- 约瑟夫环(丢手绢问题)的相关文章

【好记性不如烂笔头】约瑟夫环问题之形象解法(其实就是实实在在的模拟一下游戏过程)

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 约瑟夫环游戏 8 { 9 class Program 10 { 11 /* 12 * 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围. 13 * 从编号为k的

NYOJ 191 &amp;&amp; POJ 1012 Joseph(约瑟夫环问题)

链接:click here~~ 题意:假设有2k个人围着一个圆桌坐着,前k个是好人,后k个是坏人 .现在开始,每m个人踢掉一个,比如有6个人,m=5,那么,被踢掉的人依次是5,4,6,2,3,1.现在要求,在踢掉第一个好人前,必需把所有的坏人踢掉,问,给定一个k,求满足这个要求的最小的m,现在希望你写一个程序,快速的帮助小珂,计算出来这个m. 思路:我们来回想一下最基本的约瑟夫环问题, n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数.求最后余下的人编号

POJ 3517 And Then There Was One (约瑟夫环问题)

经典的约瑟夫环问题嘛.有点小小的变形而已.给你N个人围成一个环(编号1~N),从第M个人开始,每隔K个人报一次数,报数的人离开该环. 求最后剩下的人的编号. 约瑟夫问题的数学递推解法: (1)第一个被删除的数为 (m - 1) % n. (2)假设第二轮的开始数字为k,那么这n - 1个数构成的约瑟夫环为k, k + 1, k + 2, k +3, .....,k - 3, k - 2.做一个简单的映射. k         ----->  0 k+1    ------> 1 k+2    

poj 3517 And Then There Was One(约瑟夫环问题)

http://poj.org/problem?id=3517 讲解 n个人,编号为1~n,每次数到m的人出圈,最后一个出圈的人的编号. f[1] = 0; for(int i = 2; i <= n; i++) { f[i] = ( f[i-1] + m)%i; } printf("%d\n",f[n]+1); 这里第一次出圈的人的编号是m,然后从0开始数,每次数到k的人出圈,问最后出圈的人的编号. 注意递推顺序 #include <stdio.h> #include

HDU 5643 King&#39;s Game | 约瑟夫环变形

经典约瑟夫环 1 int f[N] ={ 0 }; 2 for(int i=2; i<=n; i++) 3 { 4 f[i] = (f[i-1] + k) % i; 5 } 变形:k是变化的 #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <stdlib.h> #include <queue> #in

tc 147 2 PeopleCircle(再见约瑟夫环)

SRM 147 2 600PeopleCircle Problem Statement There are numMales males and numFemales females arranged in a circle. Starting from a given point, you count clockwise and remove the K'th person from the circle (where K=1 is the person at the current poin

POJ 3517 And Then There Was One(约瑟夫环-递推or模拟)

POJ 3517 题目: n  k m 数字1到n成环,先叉数字m,往下数k个,直到最后只有一个数字,输出它. 链表模拟: #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<cmath> #include<vector> #incl

Roman Roulette(约瑟夫环模拟)

Roman Roulette Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 286    Accepted Submission(s): 105 Problem Description The historian Flavius Josephus relates how, in the Romano-Jewish conflict of

1074 约瑟夫环 V2

1074 约瑟夫环 V2 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 收藏 关注 N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人重新从1开始报数.问最后剩下的人的编号. 例如:N = 3,K = 2.2号先出列,然后是1号,最后剩下的是3号. Input 2个数N和K,表示N个人,数到K出列.(2 <= N <= 10^18, 2 <= K <= 1000) Output 最后剩下的人的编号 Input