请教一道编程题

KingI 2003-10-19 10:53:07
有n个人按顺序排成一个圆圈,开始报数(从1到3),报到3的人退出圆圈,问:最后剩下的那个人是原来的第几号?
...全文
65 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
sky_apple 2003-10-19
  • 打赏
  • 举报
回复
//josephus问题是说,一群小孩围成一圈,任意假定一个数m,从第一个小孩起,
//顺时针方向数,每数到第m个小孩时,该小孩离开,小孩不断离开,圈子不断缩小
//最后一个小孩便是胜利者。究竟是第几个小孩呢?
#include<iostream>
using namespace std;
void main()
{
//建立小孩数组
const int num=0;//小孩数
int interval;//每次数interval个小孩,便让小孩离开
int a[num];//小孩数组
//给小孩编号
for(int i=0;i<num;i++)//小孩的编号只与小孩数有关
a[i]=i+1;
//输入数小孩间隔
cout<<"please input the interval:";//输入一个小孩个数
cin>>interval;
//将全体参加的小孩输出
for(int i=0;i<num;i++)//顺序输出开始时的小孩编号
cout<<a[i]<<","<<endl;
int k=1;//标识处理第k个离开的小孩
int i=-1;//数组下标(下一个值0就是第一个小孩的下标)
//处理获胜的小孩
while(1)
{
//在圈中数interbal个小孩
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";//输出胜利者
cin.get();
}



pxwzd123 2003-10-19
  • 打赏
  • 举报
回复
约瑟夫环问题
约瑟夫环问题:设编号为1,2,3,……,n的n(n>0)个人按顺时针方向围坐一圈,每个人持有一个正整数密码。开始时任选一个正整数做为报数上限m,从第一个人开始顺时针方向自1起顺序报数,报到m是停止报数,报m的人出列,将他的密码作为新的m值,从他的下一个人开始重新从1报数。如此下去,直到所有人全部出列为止。令n最大值取30。要求设计一个程序模拟此过程,求出出列编号序列。

#include <stdlib.h>
#include <alloc.h>

struct node
{
int number; /* 人的序号 */
int cipher; /* 密码 */
struct node *next; /* 指向下一个节点的指针 */
};

struct node *CreatList(int num) /* 建立循环链表 */
{
int i;
struct node *ptr1,*head;

if((ptr1=(struct node *)malloc(sizeof(struct node)))==NULL)
{
perror("malloc");
return ptr1;
}
head=ptr1;
ptr1->next=head;
for(i=1;i<num;i++)
{
if((ptr1->next=(struct node *)malloc(sizeof(struct node)))==NULL)
{
perror("malloc");
ptr1->next=head;
return head;
}
ptr1=ptr1->next;
ptr1->next=head;
}
return head;
}

main()
{
int i,n=30,m; /* 人数n为30个 */
struct node *head,*ptr;
randomize();
head=CreatList(n);
for(i=1;i<=30;i++)
{
head->number=i;
head->cipher=rand();
head=head->next;
}
m=rand(); /* m取随机数 */
i=0; /* 因为我没办法删除head指向的节点,只会删除head的下一节点,所以只能从0数起。*/
while(head->next!=head) /* 当剩下最后一个人时,退出循环 */
{
if(i==m)
{
ptr=head->next; /* ptr记录数到m的那个人的位置 */
printf("number:%d\n",ptr->number);
printf("cipher:%d\n",ptr->cipher);
m=ptr->cipher; /* 让m等于数到m的人的密码 */
head->next=ptr->next; /* 让ptr从链表中脱节,将前后两个节点连接起来 */
head=hea/d->next; /* head移向后一个节点 */
free(ptr); /* 释放ptr指向的内存 */
i=0; /* 将i重新置为0,从0再开始数 */
}
else
{
head=head->next;
i++;
}
}
printf("number:%d\n",head->number);
printf("cipher:%d\n",head->cipher);
free(head); /* 让最后一个人也出列 */
}

是这个问题的简化版本吧,以前的程序。
ttlb 2003-10-19
  • 打赏
  • 举报
回复
// C语言版
#include <stdio.h>

void josephus(int iTotal, int iInter)
{
static int *iArr = new int[iTotal];
int j = 0; // j:间隔数iInter的游标
int iOut = 0;
for (int i = 0; ; ++i) // i:全部小孩iTotal的游标
{
i %= iTotal;

if (1 == iArr[i]) // 已经出去了
continue;
++j; // 此位置上的小孩还没有出去,j++;
if (iInter == j) // 已经输了iInter 个小孩,让这个小孩出去
{
iArr[i] = 1;
j = 0;
++iOut;
printf("%d\n",i);
}
if (iTotal == iOut) // 全出去了
return;
}
}

int main()
{
int iTotal = 0, iInter = 0;
printf("input total number: ");
scanf("%d",&iTotal);
printf("input internal: ");
scanf("%d",&iInter);
josephus(iTotal, iInter);
return 0;
}
ttlb 2003-10-19
  • 打赏
  • 举报
回复
http://expert.csdn.net/Expert/topic/2367/2367799.xml?temp=.9312097
不是已经问过了吗?
danpianji2002 2003-10-19
  • 打赏
  • 举报
回复
约瑟夫问题
akiko 2003-10-19
  • 打赏
  • 举报
回复
http://paddy.myrice.com/program/34.htm
leyt 2003-10-19
  • 打赏
  • 举报
回复
是想要个程序吗

69,370

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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