一个C++约瑟夫环的问题

2025-01-02 03:21:35
推荐回答(4个)
回答1:

#include 

struct person

{

 int id; 

 int pwd; 

 struct person *link; 

}; 

int main(int argc, char *argv[])

{

 struct person p[7] = {{1,3,p+1}, {2,1,p+2}, {3,7,p+3}, {4,2,p+4}, {5,4,p+5}, {6,8,p+6}, {7,4,p}}; //初始化约瑟夫环

 int M = 20; 

 int cnt; //报数

 struct person *cur = p, *pre = p + 6; 

 while(pre!=cur) //判断最后剩一个

 {

  cnt = 1; //重新报数

  while(cnt < M)

  {

   pre = pre->link; 

   cur = cur->link; 

   ++cnt; 

  }

  printf ("%d ", cur->id); //打印出局的 

  pre->link = cur->link; //出局

  M = cur->pwd; //更换密码

  cur = cur->link; //初始化下一个位置

 }

 printf ("%d ", cur->id); //打印获胜者

 return 0;  

}

这样就可以了,用数学解法不好解,直接用链表建模,需要扩展就自己写一下,思路就是上面那样的,为了省事没用栈内存,人数不确定时候可以使用占内存。

运行结果:

回答2:

#include
#include

/*结构体*/
struct node
{
int num,secret;
struct node *next;
};

/*建造循环链表,并返回头指针*/
node *creatlinklist(int m)
{
node *head,*p,*q;
head=p=(node *)malloc(sizeof(node));
int j;
printf("输入第1个密码:");
scanf("%d",&j);
p->secret=j;
p->num=1;
for(int i=2;i<=m;i++)
{
q=(node *)malloc(sizeof(node));
printf("输入第%d个密码:",i);
scanf("%d",&j);
q->secret=j;
q->num=i;
p->next=q;
p=q;
};
p->next=head;
return(head);
};

/*按规则实现排列*/

/*第一种方法 找到一个打印一个*/

/*void fun(node *H,int K,int M)
{
int i,j;
node *p;
for(j=1;j<=M-2;j++)
{
for(i=1,p=H;inext);
K=p->next->secret;
printf("%d\t",p->next->num);
p->next=p->next->next;
H=p->next;
};
for(i=1,p=H;inext);
printf("%d\t",p->num);
printf("%d\t",p->next->num);
printf("\n");
};*/

/*第二种方法 把循环链表按规则变成单链表*/

void fun(node *H,int K,int M)
{
node *p,*q,*nhead;
int i,e;
/*按规则找到第一个节点,并将其作为新链表头结点nhead ,尾节点q*/
for(i=1,p=H;inext);
nhead=q=p->next;
K=q->secret;
p->next=p->next->next;
/*按规则找到剩下的节点并用尾插法连到新链表尾节点后*/
for(e=1;e<=M-3;e++)
{
for(i=1,p=p->next;inext);
K=p->next->secret;
q->next=p->next;
q=p->next;
p->next=p->next->next;
};
for(i=1,p=p->next;inext);
q->next=p;

/*输出序列*/
printf("输出密码序列:\n");
for(p=nhead,i=1;i<=M;i++,p=p->next)
{
int j=p->secret;
printf("%d\t",j);
};
printf("\n输出顺序序列:\n");
for(p=nhead,i=1;i<=M;i++,p=p->next)
{
int j=p->num;
printf("%d\t",j);
};
printf("\n");
};

/*主程序*/
void main()
{
int n,k;
node *h;
printf("输入节点数n:");
scanf("%d",&n);
printf("输入k值:");
scanf("%d",&k);
h=creatlinklist(n);
fun(h,k,n);
}

回答3:

#include
#include
#include
#define LEN 10 //列长度
class ysf
{
public:
ysf *pre;
ysf *next;
int code,key;
};

void main()
{
int code;
cout<<"请输入所用密码:";
cin>>code;
code--;
/*rand((unsigned)time(NULL));*///初始化随机数
ysf link[LEN];
for(int i=0;i {
link[i].key=i+1;
link[i].next=link+i+1;
link[i].pre=link+i-1;
link[i].code=code;//(int)(rand()/1000);//此处现在为一直用一个code计数,可改为随机产生
}
link[i-1].next=link;
link[0].pre=link+i-1;

ysf *p=link;
int c=0;
while(p->next!=p)//在指向自身前一直循环
{
for(c=1;c<=code;c++)//计数,直到指向该出列的节点
p=p->next;
code=p->code;
cout<key<<'\t';
p->next->pre=p->pre;//在循环队列中删除当前节点
p->pre->next=p->next;
p=p->next;//指向下一个开始的节点
}
cout<key<}
以前写的,自己改改就行了

回答4:

好玩的游戏。我去试试。