17世纪法国数学家加斯帕在《数学的游戏问题》中讲的一个故事:n个教徒和n个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了个办法:2n个人围成一个圆圈,从第一个人开始依次循环报数,每数到第九个人就将他扔入大海,如此循环直到仅剩n个人为止 。问怎样的排法,才能使每次投入大海的都是非教徒。
【输入】 输入文件由一行构成,就是n的值。
【输出】 输出文件中是一行字符串,字符串由n个‘@’字符(代表教徒)和n个‘+’ 字符(代表非教徒)排列构成。该排列使得按照前面的约定每次投入大海的都是非教徒。
【输入范例】 15
【输出范例】 @@@@+++++@@+@@@+@++@@+++@++@@+
构建循环链表,将2n先定义为教徒赋值为@,通过指针操作链表结点寻找第九个人,将其赋值为+,若遇到已赋值为+的则跳过将其后续赋值为+,自写代码若有错误欢迎指出
代码
#include<stdio.h>/*循环链表 数组*/
#include<stdlib.h>
typedef struct dnote
{
char data;
struct dnote *next;
//struct dnote *rear;
}node,*linklist;
linklist createlink(linklist L,int m,int n)/*尾插建表*/
{
node *s,*r;
int i;
L=(linklist)malloc(sizeof(node));
r=L;
for(i=0;i<m;i++)
{
s=(linklist)malloc(sizeof(node));
s->data='@';
r->next=s;
r=s;
}
s->next=L->next;//链尾指向链头
r=L->next;//找到第九个人
while(m!=n)
{
i=1;
while(i!=9)
{
if(r->data=='@')
{
i++;
r=r->next;
}
else
r=r->next;
}
while(r->data=='+')
{
r=r->next;
}
//if(r->data=='+')
//r->next->data='+';
//else
r->data='+';
m--;
}
/*2+@@+ 3+++@@@*/
r=L->next;//输出
for(i=0;i<(2*n);i++)
{
printf("%c",r->data);
r=r->next;
}
return 0;
}
int main()
{
linklist L=NULL;
int n,m;
printf("输入n的值");
scanf("%d",&n);
m=2*n;
createlink(L,m,n);
return 0;
}