2022年3月20日更新:
这不就是一个简单的利用循环队列就可以实现的东西嘛,没学过数据结构就是麻烦。
原文章:
前言
此问题,作者搜索了好久,也没有找到好懂的正确的答案,所以就自己写了一个c++程序,来把所有的可能遍历一遍
题目及代码如下
一、题目
说从前啊,有一个富人,他有30个孩子,其中15个是已故的前妻所生,其余15个是继室所生,这后一个妇人很想让她自己所生的最年长的儿子继承财产,于是,有一天,他就向他说:"亲爱的丈夫啊,你就要老了,我们应该定下来谁将是你的继承人,让我们把我们的30个孩子排成一个圆圈,从他们中的一个数起,每逢到10就让那个孩子站出去,直到最后剩下哪个孩子,哪个孩子就继承你的财产吧!"富人一想,我靠,这个题意相当有内涵了,不错,仿佛很公平,就这么办吧~不过,当剔选过程不断进行下去的时候,这个富人傻眼了,他发现前14个被剔除的孩子都是前妻生的,而且下一个要被剔除的还是前妻生的,富人马上大手一挥,停,现在从这个孩子倒回去数, 继室,就是这个歹毒的后妈一想,倒数就倒数,我15个儿子还斗不过你一个啊~她立刻同意了富人的动议,你猜,最后谁做了继承人呢?
二、思路
用一个数组,存放从1~30的数字,进行剔除,谁被剔除,该数组元素变为0,并且把这个数组元原本的值赋给另一个数组b[15],该数组用来最终输出都哪些孩子被剔除了,之后再反向遍历即可:
代码如下(cpp代码):
环境:vs2019
#include <iostream>
using namespace std;
int main ()
{
//定义一个数组a[30],数组中分别存放数字1~30,表示30个孩子
int a[30];
for (int i = 0; i < 30; i++)
a[i] = i + 1;
//定义数组 b[15]用来存放被剔除的人的编号
int b[15];
for (int i = 0; i < 15; i++)
b[i] = 0;
int n = 0; //用来给b数组计数
//第一阶段,正向剔除
//要求:剔除后,该数组元素对应的值为0,进行计数时,先判断该数组元素是否为0,如果为0,则不进行计数,如果不为0,则进行计数。数组的下标到29后,从下标为0的开始
int j = 0; //j的作用是用来记录有几个非零的a数组元素
for (int i = 0;;i++) //i为从1~30进行遍历
{
//每一次循环,都要判断循环的标志变量是否等于30,如果等于,就代表这是i=0的情况,从头开始遍历
if (i == 30)
i -= 30;
//判断该数组的值是否为0,如果不为0,则i+1
if (a[i] != 0)
{
j += 1;
//先看j是否要+1,如果不用,则该数组元素已经被剔除了,就不需要再判断他是否需要被剔除了。
if (j == 10 )
{
n += 1; //代表被剔除的数多一个
b[n - 1] = a[i]; //用来记录数组a的哪一个元素被剔除了
a[i] = 0;
j -= 10;
}
}
//正向遍历结束的标志
if (n == 15)
break;
} //正向遍历至此结束,已经挑选出了全部的前十四个被剔除的前妻的儿子
for (int i = 0; i < 14; i++)
{
cout << b[i] << " ";
if (i % 4 == 0&&i!=0)
cout << endl;
}
//把b[14]对应的给复原
int t = b[14];
a[t] = t;
//接下来进行反向遍历
int c[15];
for (int i = 0; i < 15; i++)
c[i] = 0; //c的作用是一个缩小版的a
j = 0, n = 0; //因为此时进行了新一轮的遍历
for (int i = b[14] - 1;; i--)
{
if (i < 0)
break;
if (a[i] != 0)
{
j += 1;
//先看j是否要+1,如果不用,则该数组元素已经被剔除了,就不需要再判断他是否需要被剔除了。
if (j == 10)
{
n += 1; //代表被剔除的数多一个
c[n - 1] = a[i]; //用来记录数组a的哪一个元素被剔除了
a[i] = 0;
j -= 10;
}
}
} //至此,反向遍历结束
//接着进行正向遍历
for (int i = 1;; i++) //i为从1~30进行遍历
{
//每一次循环,都要判断循环的标志变量是否等于30,如果等于,就代表这是i=0的情况,从头开始遍历
if (i == 30)
i -= 30;
//判断该数组的值是否为0,如果不为0,则i+1
if (a[i] != 0)
{
j += 1;
//先看j是否要+1,如果不用,则该数组元素已经被剔除了,就不需要再判断他是否需要被剔除了。
if (j == 10)
{
n += 1; //代表被剔除的数多一个
c[n - 1] = a[i]; //用来记录数组a的哪一个元素被剔除了
a[i] = 0;
j -= 10;
}
}
if (n == 15)
break;
}
for (int i = 0; i < 15; i++)
{
cout << c[i] << " ";
if (i % 4 == 0 && i != 0)
cout << endl;
}
cout << endl << endl;
for (int i = 0; i < 30; i++)
if (a[i] != 0)
cout << a[i];
return 0;
}
由于本人是初学者,代码质量比较低,仅仅提供一个大体上的思路。
最终结果是,只有编号为18的那个人,始终不会被剔除,因此,最终的继承人为18号