英文:
Count numbers deleted by removing consecutive digit pairs that don't sum to 17
问题
以下是我翻译好的内容:
问题陈述如下:
你会得到一个用十进制表示的数字,你必须通过选择两个连续的数字并删除它们来将其完全删除。但是这两个数字的和不应为17。我们称通过重复上述操作完全删除的数字为**“好数字”**。
示例:
9889
=> 删除88
得到99
99
=> 删除99
以完全删除数字。
结论:9889是好数字。
注意:我们不能删除98
或89
,因为这两个数字的和是17
。
给定一个数字 N(偶数),你需要找到模 10^9 + 7
下的好数字的数量。在计数中也包括含有前导零的 N 位数。
测试案例:
案例1:
输入:2
输出:98
案例2:
输入:4
输出:9926
案例3:
输入:442
输出:417551213
我尝试过使用各种代码来解决这个问题,但无法获得结果。
英文:
Below is the problem statement that I have:
You get number written in base 10, you have to delete it completely by choosing two consecutive digits and deleting them. But the sum of those 2 digits should not be 17. We call the numbers which are fully deleted by repeating the above operation as "Good".
Example:
9889
=> Delete88
to get99
99
=> Delete99
to fully delete number.
Conclusion: 9889 is good.
NOTE: We cannot remove98
or89
as the sum of these 2 digits is17
.
Given a number N(even) you want to find the number of good N-digit number modulo 10^9 + 7
. Include in the count the N digit numbers containing leading zeros, too.
Test Cases:
Case 1:
Input: 2
Output: 98
Case 2:
Input: 4
Output: 9926
Case 3:
Input: 442
Output: 417551213
I have tried solving this using various codes but not able to get the result.
答案1
得分: 4
每个最后一个可能的错误状态序列,必然存在一个强制性序列生成了它。观察可能的通配符位置(当然,数字选择的位置最为关键),并尝试找出模式。
在以下示例中,为了对称起见,将9替换为8;x
表示通配符:
输入长度为4,错误结果为9898:
9898
输入长度为4,错误结果为98:
989x
98x8
9x98
x898
从上面的两个示例中,我们可以清楚地看出为什么会得到输出,即9926个好的4位数。
输入长度为6,错误结果为9898:
98989x
9898x8
989x98
98x898
9x9898
x89898
输入长度为6,错误结果为9898或98:
9898xx
989xx8
98xx98
9xx898
xx9898
输入长度为6,错误结果为98:
989x9x
98x8x8
...
9x989x
...
等等。
Python代码:
# https://gist.github.com/rougier/ebe734dcc6f4ff450abf
def binom(n,k):
if not 0<=k<=n: return 0
b=1
for t in range(min(k,n-k)):
b*=n; b//=t+1; n-=1
return b
def f(n):
bads = 0
for k in range((n - 2) // 2 + 1):
bads += 9**k * binom(n, k)
return (10**n - 2 * bads) % (10**9 + 7)
print(f(442)) # 417551213
以上是翻译好的内容。
英文:
For each sequence of the last possible bad state, there must have been a forced sequence that generated it. Look at the locations of possible wild-cards (the digits that offer choice are the ones of interest, of course), and try to find a pattern.
In the following examples, for symmetry, switch 9s with 8s; x
s are wildcards:
Input length 4, bad result 9898:
9898
Input length 4, bad result 98:
989x
98x8
9x98
x898
We can clearly see from the two above why we get the output, 9926 good 4-digit numbers.
Input length 6, bad result 9898:
98989x
9898x8
989x98
98x898
9x9898
x89898
Input length 6, bad result 9898 OR 98:
9898xx
989xx8
98xx98
9xx898
xx9898
Input length 6, bad result 98:
989x9x
98x8x8
...
9x989x
...
etc.
Python code:
# https://gist.github.com/rougier/ebe734dcc6f4ff450abf
def binom(n,k):
if not 0<=k<=n: return 0
b=1
for t in range(min(k,n-k)):
b*=n; b//=t+1; n-=1
return b
def f(n):
bads = 0
for k in range((n - 2) // 2 + 1):
bads += 9**k * binom(n, k)
return (10**n - 2 * bads) % (10**9 + 7)
print(f(442)) # 417551213
答案2
得分: 1
尝试使用树来尝试每个可能的解决方案。真正的问题是,你必须预测哪些数字将保留,以及是否可以在不产生17的情况下删除它们。例如,如果你有9823,你可以删除23,但是在末尾保留98将会阻塞你。
你可以尝试构建一棵树,其中每个分支都代表一种删除的可能性。如果所有分支都被阻塞,你将回到前一个节点。
英文:
Try with using a tree to try every possible solution. The real problem is that, you have to predict what digit will stay and if you can delete them without having a sum of 17.
For exemple, if you have 9823 you can delete 23 but you'll be blocked with 98 at the end.
You can try building a tree with every branch being a possibility of deletion. If all of the branches are blocked you get back to the previous node
答案3
得分: 0
不想暴露代码内容,但是判断一个数字是否好的问题可以通过“回溯法”来解决。
solve(9889);
public static void solve(int num) {
try {
solve(num, new LinkedList<>());
System.out.println("未找到");
} catch (FoundException fe) {
System.out.printf("%d%n", num);
fe.result.forEach(pair -> System.out.printf("-> %d,删除了 %d%n",
pair.getKey(), pair.getValue()));
}
}
private static class FoundException extends RuntimeException {
public final List<Pair<Integer, Integer>> result;
public FoundException(List<Pair<Integer, Integer>> result) {
this.result = result;
}
}
private static void solve(int num, LinkedList<Pair<Integer, Integer>> partialResult) {
if (num == 0) {
throw new FoundException(partialResult);
}
int tenPower = 1;
while (num >= tenPower) {
int n = num / tenPower;
int del = n % 100;
if (del % 10 + del / 10 != 17) {
int n2 = (n / 100) * tenPower + (num % tenPower);
partialResult.addLast(new Pair<>(n2, del));
solve(n2, partialResult);
partialResult.removeLast();
}
tenPower *= 10;
}
}
该问题似乎被构想成使用一个“int”(31位无符号整数)即可解决。
因此,我尝试使用“int”而不是数字列表进行操作。
另一个特点:使用异常将深层递归中的结果传递回顶层以获得正面结果。传统方法是检查递归调用的结果。
**注意:实际问题更具有数学性质。**
英文:
Not wanting to spoil the coding, but whether a number is good, could be done with backtracking.
solve(9889);
public static void solve(int num) {
try {
solve(num, new LinkedList<>());
System.out.println("Not found");
} catch (FoundException fe) {
System.out.printf("%d%n", num);
fe.result.forEach(pair -> System.out.printf("-> %d, having deleted %d%n",
pair.getKey(), pair.getValue()));
}
}
private static class FoundException extends RuntimeException {
public final List<Pair<Integer, Integer>> result;
public FoundException(List<Pair<Integer, Integer>> result) {
this.result = result;
}
}
private static void solve(int num, LinkedList<Pair<Integer, Integer>> partialResult) {
if (num == 0) {
throw new FoundException(partialResult);
}
int tenPower = 1;
while (num >= tenPower) {
int n = num / tenPower;
int del = n % 100;
if (del % 10 + del / 10 != 17) {
int n2 = (n / 100) * tenPower + (num % tenPower);
partialResult.addLast(new Pair<>(n2, del));
solve(n2, partialResult);
partialResult.removeLast();
}
tenPower *= 10;
}
}
The problem seems to be formulated such that an int
(31 bits unsigned int) suffices.
Hence I tried working with int
instead of a list of digits.
An other feature: using an exception to return from deep inside recursion to the top level with a positive result. The traditional way would be to check the result of a recursive call.
Note: the actual problem is a more mathematical one.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论