C语言编程 约瑟夫环问题
追问:输出的是 最后剩余的号码 还有被排除的号码 如何修改一下
追问:输出的是 最后剩余的号码 还有被排除的号码 如何修改一下
答案:#include<stdio.h>
#include<stdlib.h>
void main()
{
int a[100]; /*用来放环里的每个人的,人口上限(好像在打魔兽争霸)100,当然可以再改大*/
int n,r,ctor,u; /*n是用来循环赋值的,给r个人循环赋1~u,一共r个人,ctor计数器,到了u再重新归1*/
int call(int a[],int real,int u); /*报数函数*/
for(n=0;n<=99;n++)a[n]=0; /*给所有元素赋值为0,这样以后没赋值1~u的就都为0,可以当作不存在*/
printf("/约瑟夫环 JOSEPHUS/\n\n");
printf("输入参与报数的人数\n");
scanf("%d",&r);
printf("输入报数上限\n");
scanf("%d",&u);
ctor=1;
for(n=0;n<r;n++) /*这个循环里给输入的人数都赋值,从1到u,相当于报的数*/
{
*(a+n)=ctor;
ctor++;
if(ctor>u)ctor=1;
}
call(a,r,u);system("pause"); /*调用点名函数*/
}
int call(int a[],int real,int u)
{
int n1,i;
int *p;
p=(a+u-1);
n1=0;i=u;
for(;n1<real-1;p++)
{
if(p>(a+real-1))p=a; /*如果点名点过了,就接着队伍没有出列的第一个人继续*/
if(*(p)!=0) /*如果扫描的数字不为零,说明这个人还在队列中,那么看下面*/
{
if(i>u)i=1; /*由于是剩下的人继续报数,所以当报到u这个上限时,还是要从新归1*/
if(i==u) /*当到达上限,说明这个人该出列啦,它的位置就填充为0*/
{
*(p)=0;n1++; /*n1计算着一共多少人出列,通过n1<real-1,可以留下最后一个人,这是最终目的*/
}
i++;
}
}
for(i=0;i<real;i++) /*从新扫描数组,发现不是0的就输出,到这时候肯定只剩一个数不是0了*/
if(*(a+i)!=0)printf("所剩最后一位原来的呼号是%d\n\n",i+1);
}
《天下代码一大抄……》#include<iostream>
using namespace std;
//本程序以从1开始数,数到3离队为例,其它情况只用少加修改
void make(int *base,int n,int pos,int c)
{
int j=0;
cout<<"NO. "<<++c<<" 第"<<pos+1<<"位出列"<<endl;//输出
base[pos]=0;//踢掉
if(c==n)return; //出口
while(j-3)
if(base[pos=(pos+1)%n])
j++;//递归点 ,每次数到几这个3就改到几
make(base,n,pos,c);//递归
}
int main()
{
int n,c=0,pos=2;//从N开始数,则把pos改为N-1就行了.
cout<<"请输入总人数"<<endl;
cin>>n;
int *base=new int[n];
for(int i=0;i<n;i++)
base[i]=1;
make(base,n,pos,c);
delete[]base;
system("PAUSE");
return 0;
}
上一个:怎么样才能学好C语言
下一个:c语言的符号和引用问题