你问的是正则表达式
(xxx|xxxx|xxxxx)*
匹配 xx...x,其中 x 出现 456 次。
这是 O(n+a^2) 中的一个解决方案,其中 a 是左侧数字中的最小值(在本例中为 3)。
假设您的数字是 6,7,15。我将以 6x+7y+15z 形式表示的数字称为“可用”。您将检查给定的号码是否可用。
如果你能够得到某个数字 n,那么你肯定能够得到 n+6、n+12、n+18 - 一般来说,对于所有 k >= 0,n+6k。另一方面,如果你无法得到某个数字 n,那么 n-6 肯定也不可用(如果你能得到 (n-6),那么 (n-6)+6=n 将可用),这意味着 n-12, n-18, n-6k 也不可用。
假设您已确定 15 可用但 9 不可用。在我们的例子中,15=6*0+7*0+15*1 但无论如何都无法得到 9。因此,根据我们之前的推理,15+6k 可用于所有 k >= 0,而 9-6k 可用于所有 k >= 0 则不可用。如果您有某个数字除以 6 得到 3 作为余数(3、9、15、21,...),您可以快速回答:数字 <= 9 不可用,数字 >= 15 可用。
确定除以 6 的所有可能余数(即 0、1、2、3、4、5)就足够了,可用的最小数是多少。(我刚刚表明余数 3 的这个数字是 15)。
怎么做:创建一个顶点为 0、1、2、3、4、5 的图形。对于给定的所有数字 k (7,15 - 我们忽略 6),添加一条从 x 到 (x + k) mod 6 的边。给它权重 (x + k) div 6. 使用Dijkstra 算法,使用 0 作为初始值节点。算法找到的距离将正是我们正在搜索的那些数字。
在我们的例子中 (6,7,15),数字 7 产生 0 -> 1(权重 1),1 -> 2(权重 1),2 -> 3(权重 1),...,5 -> 0(权重 1)和数字 15 给出 0 -> 3(权重 2)、1 -> 4(权重 2)、...、5 -> 1(权重 2)。从 0 到 3 的最短路径有一条边 - 它的权重为 2。因此 6*2 + 3 = 15 是余数为 3 的最小数字。6*1 + 3 = 9 不可用(好吧,我们之前手动检查过)。
和正则表达式有什么联系?好吧,每个正则表达式都有一个等效的有限自动机,我构建了其中一个。
这个问题,允许多个查询,出现在波兰奥赛上,我翻译了解决方案。现在,如果你现在听到有人说计算机科学对真正的程序员没有用处,那就打他的脸吧。