josephus问题

yiyangdemeng 2010-06-02 04:01:40
#include <iostream.h>

void main()
{
//建立小孩数组
const int num=10 ; // 定义常量 小孩数为10
int interval; // 定义每次数interval 个小孩,便让该小孩离开
int a[num] ; // 定义小孩数组


//给小孩编号 顺序编为 1,2,3,…,10
for(int i=0; i<num; i++)
a[i]= i+1; //小孩从1号开始编

//输入数小孩的间隔
cout<<"please input the interval:" ; //输入一个间隔数
cin>>interval;

//将全体参加的小孩输出,用于比较
for( i=0; i<num; i++) //输入全体小孩的编号
cout<<a[i]<<",";
cout <<endl;

int k=1 ; //标识处理第k个离开的小孩
i=-1 ; //数组下标(下一个值0就是一个小孩的下标) (注:在VC++中 int k=1;int i=-1是错的)

//处理获胜前的小孩
while(1) //一直循环执行
{// 执行范围:在圈中的interval个小孩
for(int j=0;j<interval;)
{
i=(i+1)%num; //对下标加1求模,(其实只是针对头和尾的)
if(a[i]!=0) //如果该元素的小孩在圈中,则承认数数有效
j++;
}
if(k==num) break; //如果该小孩是最后一个,则跳出循环

cout<<a[i]<<","; //输出小孩离开后的编号
a[i]=0; //标识小孩已经离开

k++; //准备处理下一个圈中的小孩
}

// break语句跳转到此
cout<<"\nNo."<<a[i]<<"boy's won. \n"; //输出胜利者
}

c++执行结果:

please input the interval: 5
1,2,3,4,5,6,7,8,9,10,
5,10,6,2,9,8,1,4,7,
No.3boy's won.
Press any key to continue


int k=1 ; //标识处理第k个离开的小孩
i=-1 ; //数组下标(下一个值0就是一个小孩的下标) (注:在VC++中 int k=1;int i=-1是错这仍然不懂,这是干什么用的?i=(i+1)%num; //对下标加1求模,(其实只是针对头和尾的)
if(a[i]!=0) //如果该元素的小孩在圈中,则承认数数有效
j++;
这一段也不懂,怎么看怎么理解不了,真是头疼了,加一求模是什么意思了?
...全文
285 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
hurryboylqs 2010-06-03
  • 打赏
  • 举报
回复
约瑟夫环,每本数据结构的书都有
starsoul0927 2010-06-03
  • 打赏
  • 举报
回复
//头文件
#ifndef EX2_3H
#define EX2_3H

struct Node
{
int num;
Node *next;
};

class List
{
private:
int K;
Node *pbegin;
Node *pcurrent;
Node *pivot;
public:
List( int );
void Find( int );
void Count( int );
void Display();
void Delete();
};

class Jose
{
private:
int n;
int s;
int m;
public:
Jose( int, int, int );
void Getout();
};

#endif

//实现
#include <iostream>
#include <iomanip.h>
#include "EX2_3h.h"

List::List( int n )
{
K = 1;
int i = 1;
pcurrent = pbegin = new Node;
pcurrent -> num = i;
for( i = 2; i <= n - 1; i++ )
{
pcurrent ->next = new Node;
pcurrent = pcurrent -> next ;
pcurrent -> num = i;
}
pcurrent ->next = new Node;
pcurrent = pcurrent ->next;
pcurrent -> num = i;
pcurrent -> next = pbegin;
}

void List::Find ( int s )
{
int i;
for( i = 1; i < s; i ++ )
pcurrent = pcurrent ->next;
pivot = pcurrent;
}

void List::Count( int m )
{
for( int i = 1; i < m; i ++ )
pcurrent = pcurrent -> next;
pivot = pcurrent;
pcurrent = pcurrent -> next;
}

void List::Display()
{
cout <<"●第 "<<setw(10)<<K++<<" 个出列的编号为: "<<setw(10)<<pcurrent -> num << endl;
}

void List::Delete()
{
pivot -> next = pcurrent -> next;
Node *ptr = pcurrent;
pcurrent = pivot;
delete ptr;
}

Jose::Jose( int N = 0, int S = 0, int M = 0 )
{
n = s = m = 0;
cout << "\n◆ 请输入:总人数_开始数_间隔数:\n◆.........?: ";
char enter('N');
while(enter != 'Y')
{
cin >> N >> S >> M ;
if( N < 2 || S < 1 || M < 1 || S > N )
{
char warn;
cout << "\n◆ -_- 您输入的数据不合法!\n";
cout << "◆继续请按 Y !◆退出请按 N !(注意大写哦^_^)\n◆.........?: ";
cin >> warn;
if( warn == 'N')
return ;
}
else
{
n = N;
s = S;
m = M;
cout <<"◆ 您输入了:"<< n <<" -- "<< s <<" -- "<< m << endl ;
cout << "◆ 确认请按 Y ! ◆ 重新输入请按 N !(注意大写哦^_^)\n◆.........?: ";
cin >> enter ;
}
if(enter != 'Y')
cout << "◆ 请重新输入您的数据:\n◆.........?: ";
}
cout << endl<<"◆ 请稍等,正在为您解决问题......\n\n";
}

void Jose::Getout()
{
List list( n );
list.Find( s );
for( int i = n; i > 0; i -- )
{
list.Count( m );
list.Display();
list.Delete();
}
}
//测试程序
#include <iostream>
#include "EX2_3h.h"

int main()
{
std::cout << "◆^_^ 欢迎使用!\n◆^_^ 很高心为你解决Josephus问题:\n";
Jose a( 0, 0, 0);
a.Getout();
char c;
std::cout << "\n◆想再解决一个请按 Y !退出请按 N !(注意大写哦^_^)\n◆.........?: ";
std::cin >> c;
while(c != 'N')
{
Jose a(0, 0, 0);
a.Getout();
std::cout << "\n◆想再解决一个请按 Y !退出请按 N !(注意大写哦^_^)\n◆.........?: ";
std::cin >> c;
}
std::cout << "\n◆谢谢使用!\n◆再见!^_^\n\n";
return 0;
}
dskit 2010-06-02
  • 打赏
  • 举报
回复
knop1027 2010-06-02
  • 打赏
  • 举报
回复
i=-1;没啥问题
可以修改如下

for(int j=0;j<interval;)
{
i=(i+1)%(num-1); //对下标加1求模,(其实只是针对头和尾的)
if(a[i]!=0) //如果该元素的小孩在圈中,则承认数数有效
j++;
knop1027 2010-06-02
  • 打赏
  • 举报
回复
i=(i+1)%num;
就是让元素一个个往前加,且保证i不超过最大的num,其实就相当于加到10,再把i置0
if(a[i]!=0)
每个被剔除的小孩,这个小孩所在的数组中的位置就会被置0,表示这个小孩已经离开,只有a[i]不等于0,表示i位置的小孩还没被剔除
不知道说的还明白啊
其实就是从0开始数,数interval个,被数到的位置就置0,直到剩下最后一个小孩就是获胜
weixiaoshashou 2010-06-02
  • 打赏
  • 举报
回复
小孩玩游戏,数到谁谁离开吧。
///////////////////////////////////////
int k=1 ; //标识处理第k个离开的小孩
i=-1 ; //数组下标(下一个值0就是一个小孩的下标) (注:在VC++中 int k=1;int i=-1是错这仍然不懂,这是干什么用的?i=(i+1)%num; //对下标加1求模,(其实只是针对头和尾的)
if(a[i]!=0) //如果该元素的小孩在圈中,则承认数数有效
j++;
这一段也不懂,怎么看怎么理解不了,真是头疼了,加一求模是什么意思了?
///////////////////////////////////////
i=-1肯定不行啊,数组下标怎么能为-1呢
求模就是为了在他们之间转圈啊。
azure110 2010-06-02
  • 打赏
  • 举报
回复
不懂 你说的 josephus是什么算法;所以看不懂你要写的是什么;

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧