#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
#define bingo 1;
#define fail 0;
typedef int Status;
typedef struct Node{
struct Node *next;
int data;
}LinkList;
//创建循环列表
int getValue(int* sum,int* loop,int* alive){
printf("参加游戏总人数为(人数>1):");
while(1){
scanf("%d",sum);
if(*sum>1)
break;
printf("输入有误\n");
}
printf("循环数字为(循环基数>1):");
while(1){
scanf("%d",loop);
if(*loop>1)
break;
printf("输入有误\n");
}
printf("最后活着的人数为(0<=人数<=%d):",*sum);
while(1){
scanf("%d",alive);
if(*alive>=0&&*alive<=*sum){
printf("\n");
break;
}
printf("输入有误");
}
return bingo;
}
LinkList *createCircleList(int n){
LinkList *s,*p,*head;
head = new LinkList();
s = new LinkList();
head->next = NULL;
s = head;
if(n!=0){
for(int i=1;i<=n;i++){
p = new LinkList();
if(!p)
exit(0);
p->data = i;
p->next = s->next;
s->next = p;
s = p;
//printf("%d->",p->data);
}
p->next = head->next;
}
delete head;
return p;
}
int ysfList(LinkList* p,int sum,int loop,int alive){
LinkList *q,*s;
//查找第几个位置
p = p->next; //p是第一个结点
s = new LinkList();
int ralive,i;
int ppp = p->data;
i = 1;
ralive = sum-alive;//需要循环的总次数
printf("==================================\n");
while(ralive){
//ralive的自减,
if(p!=p->next){
for(int j=1;j<loop-1;j++)
p = p->next;
q = p->next;
p->next = q->next;
p = q->next;
printf(" %4d号被杀\n",q->data);
delete q;
}else{//只有一个结点的时候
printf(" %4d号被杀\n",p->data);
p = NULL;
}
--ralive;
}
printf("\n");
printf("==================================\n");
if(p!=NULL){
printf("幸存玩家是:\n");
q = p;
int num = 1;
while(p->next!=q){
printf(" %3d号 ",p->data);
p = p->next;
int pp = p->data;
int qq = q->data;
delete q;
num++;
if(num==6)
{
printf("\n");
num = 1;
}
}
printf(" %d号 ",p->data);
}else{
printf(" 所有玩家均已丧生");
}
printf("\n\n");
}
int main(){
LinkList *p;
int sum=0,loop=0,alive=0;
getValue(&sum,&loop,&alive);
p = createCircleList(sum);
ysfList(p,sum,loop,alive);
return 0;
}
代码效果图为
参加游戏总人数为(人数>1):41
循环数字为(循环基数>1):7
最后活着的人数为(0<=人数<=41):30
==================================
7号被杀
14号被杀
21号被杀
28号被杀
35号被杀
1号被杀
9号被杀
17号被杀
25号被杀
33号被杀
41号被杀
==================================
幸存玩家是:
2号 3号 4号 5号 6号
8号 10号 11号 12号 13号
15号 16号 18号 19号 20号
22号 23号 24号 26号 27号
29号 30号 31号 32号 34号
36号 37号 38号 39号 40号
Process returned 0 (0x0) execution time : 14.424 s
Press any key to continue.
对于特定问题求解
据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
typedef int Status;
typedef struct Node{
struct Node *next;
int data;
}LinkList;
//创建循环列表
LinkList *CreateCircleList(int n){
LinkList *s,*p,*head;
head = new LinkList();
s = new LinkList();
//head->next = head;
head->next = NULL;
s = head;
if(n!=0){
//p = head->next;
for(int i=1;i<=n;i++){
p = new LinkList();
if(!p)
exit(0);
p->data = i;
p->next = s->next;
s->next = p;
s = p;
//printf("%d->",p->data);
}
p->next = head->next;
}
delete head;
return p->next;
}
int main(){
//把头指针返回了后,
int sum = 41;
int loop = 3;
LinkList *s,*p,*head;
//q = new LinkList();
p = CreateCircleList(sum);
//int s;
//s = p->next->data;
while(p!=p->next->next){
s = new LinkList();
for(int j=1;j<loop-1;j++)
p = p->next;
//printf("%d->", p->next->data);
s = p->next;
p->next = s->next;
delete s;
p = p->next;
}
printf("最后剩得两人是:%d %d",p->data,p->next->data);
return 0;
}
运行结果为
最后剩得两人是:16 31
Process returned 0 (0x0) execution time : 0.044 s
Press any key to continue.