看到这表情包,突然想给自己出一道练习题

其实这个表情包也流传了许久了,可我每次看到都觉得十分不可思议,为什么一定是163/326这对数字?毫无疑问,这是一对很特别的数字,消去相等的数位后,竟然得到了它们的最简整数比。查了一下,这种现象叫做偶然对消。
我想知道还有没有更多类似的数字。正好,最近在学数据结构,C语言虽然感觉挺不智能的,但还是得练,书上的题练多了心累,干脆就以找到类似的数字作为自定义地图休息一下吧。
【目标】
寻找符合条件的十进制正整数a、b,满足:消去相等的数位后做比,一定是它们的最简整数比。
【代码】
以实现功能为主,可读性和效率都没有经过调整优化。

主函数双循环,保证输入算法的分子小于恒小于分母。函数HaveSimplerForm的返回值为布尔类型,返回该对正整数是否有相等的可消去数位,另使用一个布尔类型b来输出是否满足目标条件。如果满足,输出最简整数比到x、y并打印结果。

实现算法的函数内部也是用的双循环,内层还有一次递归。大概思路就是判断a的个位和b的个位是否相等,如果相等的话,把它们删去个位后的数字输入内层递归,再调用一次;否则判断a的个位和b的十位。重复直到递归返回值为false,说明已经删到只剩下一位了,不能删了,这时判断剩下的数字之比是否满足最简整数比,满足的话把值输出到e和f,否则输出false的布尔型变量。
这里我自己额外设了一个比较苛刻的条件,即如果一对数字有多种可以消去的方法,例如1636/3236,分母消第一个3和第二个3得到的结果是不同的,那就要满足任意一种消去方法都可以得到最简整数比的结果。因此只要一个结果不对,输出了false值,那么整个递归树都可以直接返回了。另外要单独判定,如果递归深度为0,即原始数据即将返回时,如果没有进行过任何一次数位消去,直接输出false,毕竟输出默认为true,如果根本没有办法消去的一对数直接返回的话,根本没有经过最简整数比的判断,输出还是true,这样就不对了。

在实现算法的函数中还出现了一些自定义函数。其中求最大公约数的主要目的是求最简整数比;后面的三个不用多说,在内部的双循环里有用到。
最后让我们运行一下:

可以看到结果大致是正确的,并且可以验证,感觉挺神奇。这里图片显示的是四位数的结果,前面我第一个函数写的还是三位数,忘改了。其实三位数以内的结果一瞬间就能出来,四位数还是稍微慢了一点,大概要等个几十秒钟才能全部算完。
目前还有一个致命瑕疵,就是我没法证明我的结果是没有遗漏的,就这点破代码写写改改也花了我三个多小时的时间,感觉自己挺废的。不过得到结果的那一刻,真的是异常开心,所以还是决定把自己的经历分享出来,如果有人看的话,就当看个乐呵,顺便拿走我的结果去多搞几张表情包?