魔鬼找来49个人站一排,从1依次编号,
随机指定一个人开始123报数,
开始报数时方向是从左往右,到达一端终点后则反向,
比如,47(1)->48(2)->49(3)->48(1)->47(2)->46(3),
叫到3的被吃掉。最后的幸运儿是编号几?
typedef struct stu
{
int number; //编号
int turn; //报数
struct stu *last;
struct stu *next;
} Member;
void list_spawn(); //链表生成
void gamestart_1(Member *start, int _turn); //正序报数
void gamestart_2(Member *start, int _turn); //逆序报数
Member *head, *end, *temp,p[49]; //head头指针,end为指针,temp游标
int count = 0; //淘汰总数
void list_spawn()
{
int i;
for (i = 0; i < 49; i++)
{
p[i].number = i + 1;
p[i].turn = 0;
if (i>0)
{
p[i].last = &p[i - 1];
p[i - 1].next = &p[i];
p[i].next = NULL;
}
p[0].last = NULL;
head = &p[0];
end = &p[48];
}
}
//正序报数
void gamestart_1(Member *start,int _turn)
{
temp = start;
while (temp != NULL)
{
_turn = (_turn % 3 == 0) ? 3 : (_turn % 3);
if (temp->turn == 3) //先判断是否已经为3
{
temp = temp->next; //如果是就不参与报数,游标直接移动到下一个。
continue;
}
count = (_turn == 3) ? (count + 1) : count; //如果刚好叫到3,则淘汰人数增加1人。
temp->turn = _turn;
printf("\n接下来%d号叫%d,当前真淘汰总数是%d", temp->number, _turn, count);
getchar();
_turn++;
temp = temp->next;
}
if (count == 48) return;
gamestart_2(end->last, _turn); //到一端后反向
}
//倒序报数
void gamestart_2(Member *start,int _turn)
{
temp = start;
while (temp != NULL)
{
_turn = (_turn % 3 == 0) ? 3 : (_turn % 3);
if (temp->turn == 3) //先判断是否已经为3
{
temp = temp->last; //如果是就不参与报数,游标直接移动到下一个。
continue;
}
count = (_turn == 3) ? (count + 1) : count; //如果刚好叫到3,则淘汰人数增加1人。
temp->turn = _turn;
printf("\n接下来%d号叫%d,当前真淘汰总数是%d", temp->number, _turn, count);
getchar();
_turn++;
temp = temp->last;
}
if (count == 48) return;
gamestart_1(head->next, _turn); //到一端后反向
}
void main()
{
list_spawn();
temp = head;
int start = rand() % 49 + 1;
printf("从%d号开始", start);
temp = head;
while (temp != NULL)
{
if (temp->number == start)
{
gamestart_1(temp, 1);
break;
}
temp = temp->next;
}
temp = head;
while (temp != NULL)
{
if (temp->turn != 3)
{
printf("最后剩下的是%d号", temp->number);
break;
}
temp = temp->next;
}
getchar();
}
###数组写法
void main()
{
int a[49] = { 0 },
count = 0, //count代表淘汰人数
add = 1, //add代表下标移动方向,1表示从左往右,-1表示从右往左
n, //表示指定的起点
turn = 1, //表示当前要报的数字
i;
printf("请任意输入一个数字,用于指定开始位置:");
scanf("%d", &n); getchar();
printf("现在游戏开始,首先从第%d个人开始报数:", n);
i = n - 1;
while (count < 48)
{
if (i >= 48)
{
add = -1;
}
else if (i <= 0)
{
add = 1;
} //确保到达一端后能顺利反向
if (a[i] == 4) //先判断是否为已经淘汰的人,如果是就直接跳过
{
i += add;
continue;
}
else
{
if (turn == 3) //如果未淘汰,首先检查接下来要报的数字是否为3
{
a[i] = 4; //如果是,将其赋值为4,代表淘汰
count++; //淘汰人数加1;
turn = 1; //下一个人将从1开始报数
}
else
{
a[i] = turn; //如果本次安全,则赋值后状态为1,或2。
turn++; //那么下一个人报的数在本次基础上加1
}
i += add; //下标不停的移动
}
}
for (i = 0; i < 49; i++)
{
if (a[i] != 4)
{
printf("\n最后剩下的人的编号是:%d", i + 1);
break;
}
}
getchar();
}