找到号码

时间:2013-06-13 08:50:19

标签: c# algorithm c#-2.0

这是一个问题陈述。

考虑一个数字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#中解决它...

4 个答案:

答案 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);
            }
        }
    }
}