约瑟夫环c语言数组
㈠ 如何用c语言解约瑟夫环
按你表达的意思,如果原来每3个删除一个正确的话,把if(3=...)体中的count = 0;改为count = 1;就可以了。因为题意就变为“第一次隔3删除,以后隔2删除”了。
㈡ c语言约瑟夫环问题 请大神给我详细讲解一下这个解法的思路 谢谢!
思路:
(1)
将n个人的编号(1,2,3,。。。,n)存入数组元素num[0],num[1],。。。,num[n-1]中。
程序段为:
p=num;
/***********SPACE***********/
for(i=0;i<n;i++)
/***********SPACE***********/
*(p+i)=i+1;
(2)
模拟报数(k++;),报到3 的人出圈(即对应的数组元素num[i]设置为0),并使出圈的人数+1(m++;),然后再从头报数,。。。,当出圈人数达到n-1时,报数结束。
程序段为:
i=0;
k=0;
m=0;
while(m<n-1)
{
/***********SPACE***********/
if(*(p+i)!=0) k++;
if(k==3)
{
*(p+i)=0;
k=0;
m++;
}
i++;
if(i==n) i=0;
}
(3)
此时,数组中不为0的那个元素的值就是后留下的那位的编号,找到它输出即可:
while(*p==0) p++;
printf("%d is left\n",*p);
㈢ 约瑟夫问题 c语言数组
#include <stdafx.h>
#include <IOSTREAM.H>
#define N 63 // 猴子数
#define M 5 // 数数周期
void main()
{
// 编号
int arrId[N] = {0};
for (int i=0; i<N; ++i)
{
arrId[i] = i+1;
}
int nCount = N;
int nMod = 1;
while (nCount > 1)
{
nMod = (nMod-1+M)%nCount;
if (nMod == 0)
nMod = nCount;
cout << "猴子" << arrId[nMod-1] << "被淘汰" << endl;
for (int i=nMod; i<nCount; ++i)
{
arrId[i-1] = arrId[i];
}
--nCount;
}
cout << "最后的猴王是猴子" << arrId[0] << endl;
}
-----------------------------------------------
执行结果:
猴子5被淘汰
猴子10被淘汰
猴子15被淘汰
猴子20被淘汰
猴子25被淘汰
猴子30被淘汰
猴子35被淘汰
猴子40被淘汰
猴子45被淘汰
猴子50被淘汰
猴子55被淘汰
猴子60被淘汰
猴子2被淘汰
猴子8被淘汰
猴子14被淘汰
猴子21被淘汰
猴子27被淘汰
猴子33被淘汰
猴子39被淘汰
猴子46被淘汰
猴子52被淘汰
猴子58被淘汰
猴子1被淘汰
猴子9被淘汰
猴子17被淘汰
猴子24被淘汰
猴子32被淘汰
猴子41被淘汰
猴子48被淘汰
猴子56被淘汰
猴子63被淘汰
猴子11被淘汰
猴子19被淘汰
猴子29被淘汰
猴子38被淘汰
猴子49被淘汰
猴子59被淘汰
猴子6被淘汰
猴子18被淘汰
猴子31被淘汰
猴子43被淘汰
猴子54被淘汰
猴子4被淘汰
猴子22被淘汰
猴子36被淘汰
猴子51被淘汰
猴子3被淘汰
猴子23被淘汰
猴子42被淘汰
猴子61被淘汰
猴子16被淘汰
猴子44被淘汰
猴子7被淘汰
猴子34被淘汰
猴子62被淘汰
猴子37被淘汰
猴子13被淘汰
猴子57被淘汰
猴子53被淘汰
猴子12被淘汰
猴子28被淘汰
猴子47被淘汰
最后的猴王是猴子26
Press any key to continue
㈣ C语言,编了一个程序解决约瑟夫环问题(数组模拟1代表有人,0代表走了)下面的代码对吗
#include<stdio.h>
#defineN10
intmain()
{
inta[N];
inti,people=N,n=0;
for(i=0;i<N;i++)
a[i]=1;
i=0;
while(people>0)
{
if(a[i]==1)//非0的才统计
n++;
if(n==3)
{
a[i]=0;
people--;
printf("第%d个人离开 ",i+1);
n=0;
}
i++;
if(i==N)
i=0;
}
return0;
}
㈤ 约瑟夫环问题 用C语言数据结构数组实现....
#include<iostream>
using namespace std;
struct Node//循环节点的定义
{
int number;//编号
Node *next;
};
Node *CreateList(Node *L,int &n,int &m);//建立约瑟夫环函数
void Joseph(Node *L,int n,int m);//输出每次出列号数函数
Node *DeleteList(Node **L,int i,Node *q);//寻找每次出列人的号数
int LengthList(Node *L);//计算环上所有人数函数
void main()//主函数
{
Node *L;
L=NULL;//初始化尾指针
int n, m;
cout<<"请输入人数N:";
cin>>n;//环的长度
if(n<1){cout<<"请输入正整数!";}//人数异常处理
else
{
cout<<"请输入所报数M:";
cin>>m;
if(m<1){cout<<"请输入正整数!";}//号数异常处理
else
{
L=CreateList(L,n,m);//重新给尾指针赋值
Joseph(L,n,m);
}
}
system("pause");
}
Node *CreateList(Node *L,int &n,int &m)//建立一个约瑟夫环(尾插法)
{
Node *q;
for(int i=1;i<=n;i++)
{
Node *p;
p=new Node;
p->number=i;
p->next=NULL;
if(i==1) L=q=p;//工作指针的初始化
else
{
q->next=p;
q=q->next;
}
}
q->next=L;
if(L!=NULL){return(L);}//返回尾指针
else cout<<"尾指针异常!"<<endl;//尾指针异常处理
}
void Joseph(Node *L,int n,int m)//输出每次出列的人
{
int k;
cout<<"请输入第一个报数人:";
cin>>k;
if(k<1||k>n){cout<<"请输入1-"<<n<<"之间的数"<<endl;}
else
{
cout<<"\n出列顺序:\n";
for(int i=1;i<n;i++)
{
Node *q = new Node;
if(i==1) q=DeleteList(&L,k+m-1,q);//第一个出列人的号数
else q=DeleteList(&L,m,q);
cout<<"号数:"<<q->number<<endl;
delete q;//释放出列人的存储空间
}
cout<<"最后一个出列号数是:"<<L->number<<endl;;//输出最后出列人的号数
}
}
Node *DeleteList(Node **L,int i,Node *q) //寻找每次出列的人
{
if(i==1) i+=LengthList(*L);//顺序依次出列情况的处理方式
Node *p;
p=*L;
int j=0;
while(j<i-2) {p=p->next;j++;}
q = p->next;
p->next=p->next->next;
*L = p->next;
return(q);
}
int LengthList(Node *L)//计算环上的人数
{
if(L){cout<<"尾指针错误!"<<endl;}//异常处理
else
{
int i=1;
Node *p=L->next;
while(p!=L)
{
i++;
p=p->next;
}
return(i);
}
}
㈥ 数据结构中的约瑟夫环问题用C语言怎么编写出来啊
题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出
圈子,问最后留下的是原来第几号的那位。
1.
程序分析:这是一个比较经典的算法--约瑟夫环问题.
2.个人分析:
算法比较经典,对于这样的问题本应该使用链表的形式会比较容易.约瑟夫环算法
则体现了使用数组来完成链表该完成的功能,虽然形式上完全不相同,但却求出了
相同的结果.有异曲同工之妙.总之我个人认为是数组中非常经典的算法了.希望本
人写的代码不会叫大家啐骂!
3.程序源代码:
#include
<stdio.h>
#define
N
50
#define
S
3
void
main()
{
int
a[N];
int
i,k;
int
sum=N;
k=0;
for(i=0;i<N;i++)
a[i]=i+1;
for(i=0;i<N;i++)
printf("%-4d",a[i]);
printf("\n");
for(i=0;;i++)
{
if(sum==1)
break;
if(a[i%N]!=0)
{
k++;
}
if(k==S)
{
k=0;
//printf("%4d",a[i%N]);
a[i%N]=0;
sum--;
}
}
for(i=0;i<N;i++)
if(a[i]!=0)
printf("\n最后一个数为:%d\n",a[i]);
}
两年前念书的时候写的,献丑了!
㈦ c语言,如果用数组来解决约瑟夫环的问题
#include<stdio.h>
intmain(){
intnum[50],n,m,i,j;
intlen,start=0,counter=1;
printf("总数报数 ");
scanf("%d%d",&n,&m);
if(n<0||n>50)n=50;
if(m<1||m>n)m=n/2;
printf("人数:%d,报数:%d ",n,m);
for(i=0;i<n;++i)num[i]=i+1;//预填
len=n;//len保留队列中现有人数
while(len){
if(counter==m){
printf("%d",num[start]);
for(j=start;j<len-1;++j)
num[j]=num[j+1];
--len;
counter=1;
}
else{
++counter;
++start;
start%=len;
}
}
printf(" ");
return0;
}
㈧ c语言 约瑟夫环
以下是用“循环链表”和“数组”的方法做的!
m,n都可以输入。
s设为“1”。
这些稍稍改动就可以符合您的要求!
(这可是我两小时的心血,一定要给点分!!!)
*****************************
用循环链表做:
*****************************
#include<malloc.h>
#define LEN sizeof(struct people)
struct people
{
int num;
struct people *next;
};
struct people *creat(int n)
{
int i;
struct people *head,*p1,*p2;
head=NULL;
for(p1=p2,i=1;i<=n;i++)
{
p1=(struct people *)malloc(LEN);
p1->num=i;
if(i==1)
{
head=p1;
}
p2->next=p1;
p2=p1;
}
p1->next=head;
return(head);
}
struct people *del(struct people *p0)
{
struct people *p;
p=p0->next;
p0->next=p->next;
p->next=NULL;
free(p);
}
struct people *count(struct people *head,int n)
{
struct people *d,*p,*p0;
int i,j;
for(j=1,p=head;p->next!=p;j++)
{
if(n==1)
{
for(;p->next!=head;p=p->next){}
head=head->next;
printf("第%d个出局的----%d\n\n",j,p->next->num);
del(p);
}
else
{
for(i=1;i<n;i++)
{
p0=p;
p=p->next;
}
d=p0;
printf("第%d个出局的----%d\n\n",j,p->num);
p=p->next;
if(p->next!=p)
{
del(d);
}
}
}
return(p);
}
main()
{
struct people *head,*left;
int n;
printf("请输入人数(大于0):");
scanf("%d",&n);
if(n<=0)
{
printf("error\n");
}
else
{
head=creat(n);
printf("请输入要报的数(大于0):");
scanf("%d",&n);
if(n<=0)
{
printf("error\n");
}
else
{
left=count(head,n);
printf("留下的是:%d号\n",left->num);
}
}
}
***********************************
用数组做:
***********************************
int *del(int *a,int count,int n)
{
int index=0,i=n,x=0;
while(i>1)
{
if(a[index]!=0)
{
x++;
if(x==count)
{
printf("第%d个出局的是%d号\n",(n-i),a[index]);
a[index]=0;
i--;
x=0;
}
}
index=((index+1)%n);
}
return(a);
}
main()
{
int a[100],i,n;
int *p;
printf("请输入人数(大于0):");
scanf("%d",&n);
for(i=0;i<n;i++)
{
a[i]=i+1;
}
printf("请输入要报的数(大于0):");
scanf("%d",&i);
p=del(a,i,n);
i=0;
while(p[i]==0)
{
i++;
}
printf("最后留下的是%d号\n",p[i]);
}
㈨ 约瑟夫环(c语言)
怎么了,代码看不懂?
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。
首先我们列出一些有关约瑟夫环的结果:
1 1 2 2 3 2 4 1 5 4 6 1 7 4 8 7 9 1 10 4
11 7 12 10 13 13 14 2 15 5 16 8 17 11 18 14 19 17 20 2021 2 22 5 23 8 24 11 25 14 26 17 27 20 28 23 29 26 30 29
31 1 32 4 33 7 34 10 35 13 36 16 37 19 38 22 39 25 40 28
41 31 42 34 43 37 44 40 45 43 46 46 47 2 48 5 49 8 50 11
51 14 52 17 53 20 54 23 55 26 56 29 57 32 58 35 59 38 60 41
61 44 62 47 63 50 64 53 65 56 66 59 67 62 68 65 69 68 70 171 4 72 7 73 10 74 13 75 16 76 19 77 22 78 25 79 28 80 31
81 34 82 37 83 40 84 43 85 46 86 49 87 52 88 55 89 58 90 61
91 64 92 67 93 70 94 73 95 76 96 79 97 82 98 85 99 88 100 91
意思是,前一个数为约瑟夫环的人数,后一个数为最后出去的人的号码。
从上面的表中我们可以归纳出以下两个规则:
规则1:若上一组数字中最后保留号比人数少一,则下一数从1开始记。
例如第三组(3,2)为上一组,最后保留好为2,比3少1,下一组的数字(4,1),最后保留号为1
规则2:若上一组数字为最后保留号与人数相等,则下一数从2开始记。
㈩ 用c++数组解决约瑟夫环问题
#include<stdio.h>
int main() {
int num[50],n,m,i,j;
int len,start = 0,counter = 1;
printf("总数 报数\n");
scanf("%d%d",&n,&m);
if(n < 0 || n > 50 ) n = 50;
if(m < 1 || m > n) m = n/2;
printf("人数:%d,报数:%d\n",n,m);
for(i = 0; i < n; ++i) num[i] = i + 1; // 预填
len = n; // len保留队列中现有人数
while(len) {
if(counter == m) {
printf("%d ",num[start]);
for(j = start; j < len - 1; ++j)
num[j] = num[j + 1];
--len;
counter = 1;
}
else {
++counter;
++start;
start %= len;
}
}
printf("\n");
return 0;
}