这是一个问题陈述。
考虑一个数字2345.如果你乘以数字然后得到数字120.现在如果你再次乘以数字120,那么你将得到数字0这是一位数字。如果我添加2345的数字,那么我将得到14.如果我添加14的数字,那么我将获得5这是一位数字。
因此,任何数字都可以在某些步骤中转换为两位数字。您可以通过使用2个步骤中的数字乘法将2345转换为0,并通过使用2个步骤中的数字转换将其转换为5。现在考虑任意数字N.让我们说它可以通过在n1步骤中将数字乘以一位数字d1并通过以n2步骤将数字加到一位数字d2来进行转换。
您的任务是找到大于N且小于1000000000的最小数字,可以通过将其数字乘以小于或等于n1步的d1并将其数字加到d2小于或等于n2步来进行转换
如何在C#中解决它...
答案 0 :(得分:2)
我可以看到两个记忆问题;第一个是生成大量字符串 - 您可能希望接近以下内容:
static int SumDigits(int value)
{
int total = 0;
while (value > 0)
{
total += value % 10;
value /= 10;
}
return total;
}
(完全未经测试)
第二个问题是巨大的清单;您不需要存储(在lstString
)每个值只是为了找到最小值。记住迄今为止你所做的最好的事情。或者,如果您需要每个值的数据,则:不要将它们存储为string
。实际上,i
可以暗示无论如何(来自列表/数组中的位置),所以你真正需要的只是int[]
cnt
每个值的值。并且int[1000000000]
本身就是4GB,因此在最近的.NET版本(<gcAllowVeryLargeObjects>
)中需要大阵列支持。但更好的是:只是不要存储它。
答案 1 :(得分:2)
但它正在抛出
System.OutOfMemoryException
。
这只是意味着你的内存不足。您的限制为1,000,000,000
或大约1G。字符串引用的时间为4个字节,对于32位系统来说已经太大了。即使没有实际的字符串。
您可以将答案更紧凑地存储在int[]
数组中,但仍会显示相同的问题。
因此,降低限制或编译并在64位PC上运行。
答案 2 :(得分:2)
我认为你只是错误地接近/解释问题;这是在黑暗中刺伤:
using System;
using System.Diagnostics;
static class Program
{
static void Main()
{
// check our math first!
// You can see 2345 is converted to 0 by using multiplication of digits in 2 steps
int value, steps;
value = MultiplyToOneDigit(2345, out steps);
Debug.Assert(value == 0);
Debug.Assert(steps == 2);
// and it is converted to 5 by using addition of digits in 2 steps
value = SumToOneDigit(2345, out steps);
Debug.Assert(value == 5);
Debug.Assert(steps == 2);
// this bit is any random number
var rand = new Random();
for (int i = 0; i < 10; i++)
{
int N = rand.Next(0, MAX);
int result = Execute(N);
Console.WriteLine("For N={0}, our answer is {1}", N, result);
}
}
const int MAX = 1000000000;
//Now consider any number N.
static int Execute(int N)
{
// Let us say that it can be converted by multiplying digits to a one digit number d1 in n1
// steps and by adding digits to one digit number d2 in n2 steps.
int n1, n2;
int d1 = MultiplyToOneDigit(N, out n1),
d2 = SumToOneDigit(N, out n2);
// Your task is to find smallest number greater than N and less than 1000000000
for (int i = N + 1; i < MAX; i++)
{
int value, steps;
// which can be converted by multiplying its digits to d1 in less than or equal to n1 steps
value = MultiplyToOneDigit(i, out steps);
if (value != d1 || steps > n1) continue; // no good
// and by adding its digits to d2 in less than or equal to n2 steps.
value = SumToOneDigit(i, out steps);
if(value != d2 || steps > n2) continue; // no good
return i;
}
return -1; // no answer
}
static int MultiplyToOneDigit(int value, out int steps)
{
steps = 0;
while (value > 10)
{
value = MultiplyDigits(value);
steps++;
}
return value;
}
static int SumToOneDigit(int value, out int steps)
{
steps = 0;
while (value > 10)
{
value = SumDigits(value);
steps++;
}
return value;
}
static int MultiplyDigits(int value)
{
int acc = 1;
while (value > 0)
{
acc *= value % 10;
value /= 10;
}
return acc;
}
static int SumDigits(int value)
{
int total = 0;
while (value > 0)
{
total += value % 10;
value /= 10;
}
return total;
}
}
答案 3 :(得分:0)
A努力:)
现在一起做。你当然可以进行重构。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _17082903_smallest_greatest_number
{
class Program
{
static void Main(string[] args)
{
int N = 2344;
int n1 = 0;
int n2 = 0;
int d1 = SumDigits(N, ref n1);
int d2 = ProductDigits(N, ref n2);
bool sumFound = false, productFound = false;
for (int i = N + 1; i < 1000000000; i++)
{
if (!sumFound)
{
int stepsForSum = 0;
var res = SumDigits(i, ref stepsForSum);
if (res == d1 && stepsForSum <= n1)
{
Console.WriteLine("the smallest number for sum is: " + i);
Console.WriteLine(string.Format("sum result is {0} in {1} steps only", res, stepsForSum));
sumFound = true;
}
stepsForSum = 0;
}
if (!productFound)
{
int stepsForProduct = 0;
var res2 = ProductDigits(i, ref stepsForProduct);
if (res2 == d2 && stepsForProduct <= n2)
{
Console.WriteLine("the smallest number for product is: " + i);
Console.WriteLine(string.Format("product result is {0} in {1} steps only", res2, stepsForProduct));
productFound = true;
}
stepsForProduct = 0;
}
if (productFound && sumFound)
{
break;
}
}
}
static int SumDigits(int value, ref int numOfSteps)
{
int total = 0;
while (value > 0)
{
total += value % 10;
value /= 10;
}
numOfSteps++;
if (total < 10)
{
return total;
}
else
{
return SumDigits(total, ref numOfSteps);
}
}
static int ProductDigits(int value, ref int numOfSteps)
{
int total = 1;
while (value > 0)
{
total *= value % 10;
value /= 10;
}
numOfSteps++;
if (total < 10)
{
return total;
}
else
{
return ProductDigits(total, ref numOfSteps);
}
}
}
}