下一个陈述是练习的问题。
我做了这个解决方案。它正在执行从0到10 ^ 9的循环。但它被执行需要很多时间。所以,我认为下一步是在数字和反向之间的结果中添加一个hashmap作为键,保存结果。
但该计划仍在消耗时间。我想我可能缺少一个数学理论或另一种在更短的时间内解决时间的方法。
程序:
app_data
这些是从0到10 ^ 2的结果。我刚打印看到数字之间的关系:
#include <iostream>
#include <cmath>
using namespace std;
int reverseNumber(int n) {
int reverse = 0;
while (n > 0) {
reverse = reverse * 10;
reverse += n % 10;
n = n / 10;
}
return reverse;
}
string isNumberEvenOddOrMixed(int n) {
bool even = false;
bool odd = false;
while (n > 0) {
int rem = n % 10;
n = n / 10;
if (rem % 2 == 0)
even = true;
else
odd = true;
}
return even && odd ? "Mixed" : (even ? "Even" : "Odd");
}
int main(int argc, const char * argv[]) {
int even = 0, odd = 0, mixed = 0;
for (int i = 0; i < pow(10, 9); i++) {
// Verify if i already exists in the hashmap,
// if it is, just print the value saved.
int nReversed = reverseNumber(i);
int sum = i + nReversed;
string result = isNumberEvenOddOrMixed(sum);
if (result == "Even") even++;
else if (result == "Odd") odd++;
else mixed++;
// Save i and nReversed in a hashmap with the result
// hashmap[i] = result;
// hashmap[nReversed] = result;
cout << i << " + " << nReversed << " = " << sum << " : " << result << "\n";
}
cout << "Even: " << even << "\n";
cout << "Odd: " << odd << "\n";
cout << "Mixed: " << mixed << "\n";
return 0;
}
答案 0 :(得分:1)
以下是一些小优化想法:
1
for (int i = 0; i < pow(10, 9); i++)
此循环每次重新计算10 ^ 9。只需执行一次并将其存储在const变量
中2
我会更改“isNumberEvenOddOrMixed”函数以返回枚举值而不是字符串。无需比较,创建和销毁字符串,它将使您的性能略有提升。
答案 1 :(得分:1)
如果您只需计算奇数,偶数和混合结果,您应该能够通过计算[0,10 ^ 9]的1111111192条记录(约为总数的十分之一)来找到结果
解决方案构思
对于0到9,只需计算所有。
对于剩余值,请按以下方式思考。你不需要建造桌子,但要使用这个概念。
为相同位数的值设置一个表(让数字为r)
10 20 30 40 50 60 70 80 90
11 21 31 41 51 61 71 81 91
12 22 32 42 52 62 72 82 92
...
...
19 29 39 49 59 69 79 89 99
查看此表,您将观察到任何值的结果与其右上角位置(向上1和向右1)的结果相同。
从这个意义上讲,你应该能够看到数字r表,可以通过在第一列和最后一行查找值的结果来计算计数,然后对于每个计算的结果计算一次正确计数器(点2中对角线的值数,1到9之间的值)
计数器分配:左上角1,当向下移动到9时,将计数器增加1。右下角1,向左移动时将计数器增加1。
<强>证明强>
假设你有一个价值&#39; abcdefg&#39;和(&#39; a&#39;不等于1和&#39; bcdefg&#39;不等于0)。 在这种情况下,&#39; abcdefg&#39;的右上角位置。在上表中应该存在。
重写&#39; abcdefg&#39; as a * 10 ^(r-1)+ b * 10 ^(r-2)+ c * 10 ^(r-3)+ ... + f * 10 + g
反向&#39; abcdefg&#39;是g * 10 ^(r-1)+ f * 10 ^(r-2)+ e * 10 ^(r-3)+ ... + b * 10 + a
&#39; abcdefg&#39;的计算值是(a + g)* 10 ^(r-1)+(b + f)* 10 ^(r-2)+ (c + e)* 10 ^(r-3)+ ... +(f + b)* 10 +(g + a)
&#39; abcdefg&#39;右上角的值是&#39; abcdefg&#39; + 10 ^(r-1) - 1.我们可以把它写成&#39; a&#34; bcdefg&#34;&#39;其中一个&#34; = a + 1和g&#34; = g-1
重写&#39; a&#34; bcdefg&#34;&#39;作为&#34; * 10 ^(r-1)+ b * 10 ^(r-2)+ c * 10 ^(r-3)+ ... + f * 10 + g&#34;
&#39; a&#34; bcdefg&#34;&#39;是g&#34; * 10 ^(r-1)+ f * 10 ^(r-2)+ e * 10 ^(r-3)+ ... + b * 10 + a&#34;
&#39; a&#34; bcdefg&#34;&#39;的计算值是(a&#34; + g&#34;)* 10 ^(r-1)+(b + f)* 10 ^(r-2)+ (c + e)* 10 ^(r-3)+ ... +(f + b)* 10 +(g&#34; + a&#34;)
因为g&#34; + a&#34; = g-1 + a + 1 = g + a,我们有计算的&#39; a&#34; bcdefg&#34;&#39; 是(a + g)* 10 ^(r-1)+(b + f)* 10 ^(r-2)+(c + e)* 10 ^(r-3)+ ... +(f + b)* 10 +(g + a)和等于&#39; abcdefg&#39;
的计算值
这证明计算值与其右上角元素的计算值相同