我就直接说N个基督教和M个异教徒的情况吧,
数到K个人是指第K个人丢到海里
还是剩下K个人呢?
我就定义为
数到第K个人丢到海里,剩下n个人时停止吧
首先申请一个数组a[M+N-1]
再申请一个整型变量inumber = 0记录已经丢了多少人
还有一个整型m = 0记录数到了几号
初始化数组
for(i = 0i <= M + N - 1,i++)//使数组中的值和序号够成循环,用来数数
{
a[i] = (i + 1) % (M + N)
}
while(inumber <M+N-n)//丢够了人就不再丢了
{
int itemp = 1;//记录有没有数到k个人
if(itemp <k)
{
m = a[m]
itemp++//往后数一个人,到k个人的时候就不数了
}
a[m-1] = (m + 1) % (M + N)//丢掉第k个人后,重新排成圈
printf("%d",m + 1)//这些位置就是放异教徒的
inumber++;
}
具体程序自己写下吧
很简单的
不懂可以Hi我
//约瑟夫环://这个程序有点小问题,你自己看看吧,现在没时间改了,起始位置有点问题
#include<stdio.h>
#include <malloc.h>
int flag
typedef struct node
{int data
struct node *next
}LNode,* Linklist
Linklist CreatFromHead() //链表的初始化
{ Linklist L=NULL,s
LNode *r=NULL
int x=1
s=(Linklist)malloc(sizeof(LNode))
L = s
r= L
printf("请输入请输入报数的人数")
scanf_s("%d",&flag)
while(x!=flag+1)
{s=(Linklist)malloc(sizeof(LNode))
s->data=x
r->next=s
r=s
x++
}
s->next=L
if(r!=NULL) r->next=NULL
return L
}
Linklist Getlist(Linklist L,int i) //链表的查找函数
{Linklist p
int j
p=Lj=0
while(p->next!=NULL&&j<i)
{ p=p->next
j++
}
if(i==j)return p
else return NULL
}
Linklist treat(Linklist L,Linklist s,int k,int i) //约瑟夫环算法
{
int j=0
if(s==NULL)
{
s=L->next
}
while(j<k-1)
{
s=s->next
j++
if(s==NULL)
{
s=L->next
}
}
return s
}
int Del_Linklist(Linklist L,Linklist p) //链表结点删除函数
{Linklist s
s=L
while((s->next->data != p->data))
{
s=s->next
}
s->next=s->next->next
free(p)
return 1
}
void main()//主函数
{Linklist L
Linklist p,s
int i,k,m,n
L=CreatFromHead()
printf("请输入查找的元素位置")
scanf_s("%d",&i)
printf("请输入相隔的位置:")
scanf_s("%d",&k)
m=0
s=Getlist(L,i)
printf(".")
while(m<flag)
{
p=treat(L,s,k,i)
printf("%d\t",p->data)
s=p->next
n=Del_Linklist(L,p)
m++
}
}
约瑟夫问题这是17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。
思路:模拟扔入海中的过程,然后把剩余的位置作为教徒的位置。
注意:以下代码中的分号均为全角字符,如果拷贝这段代码并且编译的话,必须把全角的分号更改为半角的分号(也就是在输入法为英文的时候直接在键盘上输入分号)。
#include<iostream>
using namespace std;
void main() {
int i, j, k = 1, a[31];
for(i = 0; i <= 30; i++) a[i] = 0;
for(i = 1; i <= 15; i++){
for(j = 1; j <= 9; j++, k++) while(a[k]) if(++k >30) k = 1;
a[k-1] = 1;
}
printf("%d\n", k);
for(i = 1; i <= 30; i++) {
printf("%2d:%d ", i, a[i]);
if(!(i%15)) putchar('\n');
}
printf("(1为非教徒,0为教徒)\n");
}
/*
n, s, m = 30 1 9
出圈次序:
9 18 27 6 16 26 7 19 30 12
24 8 22 5 23 11 29 17 10 2
28 25 1 4 15 13 14 3 20 21
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)