数学中的海盗游戏 - 用C#解决它

时间:2015-06-07 15:33:49

标签: c# math console-application primes

我正在尝试解决以下问题:

  

有些海盗胸前充满了宝藏(金币)

     

现在已经很晚了,所以他们决定早上分开它

     

但是,其中一名海盗在半夜醒来时担心   其他海盗将窃取他的份额,所以他决定分裂   珍惜自己。

     

他把它分成相等的份额(每个盗版一个)。有一个   剩下的硬币,他扔到了船外。他占有他的份额,把其他股票放回原位,   并返回他的小屋。

     

另一名海盗醒来并做同样的事情。是的,还有   一枚额外的硬币。是的,他将那枚硬币扔到了船上。

     

......每个海盗都会在夜间做一次(是的,有一个   额外的硬币,他们每次扔掉它,然后下一个   早上醒来,把宝贝分成两等份。那里   是他们扔在船外的遗留物。他们各自拿走他们的   永远地分享和生活。

     

鉴于海盗数量,最小的硬币数量是多少   本来可以在宝箱里?

我尝试了以下操作,但任何大于8的数字都会让它瘫痪:

class Program
    {
        static long _input;
        static long _timesDivided;
        static string _output;

        static void Main()
        {
            Console.WriteLine("Enter the number of Pirates: ");

            var isValidInput = long.TryParse(Console.ReadLine(), out _input);

            if (!isValidInput)
            {
                Console.WriteLine("Please enter a valid number");
                Console.ReadKey();
                return;
            }

            Console.WriteLine("Caculating minimum treasure...\r\n \r\n");

            _timesDivided = _input + 1;

            var answer = CalculateTreasure();

            if (answer > 0)
                _output = string.Format("The minimum treasure is {0}", answer);
            else
                _output = "There was an error, please try another number";

            Console.WriteLine(_output);
            Console.ReadKey();
        }

        private static long CalculateTreasure()
        {
            long result = 0;

            try
            {
                while (true)
                {
                    result++;

                    while (true)
                    {
                        if (result % _input == 1)
                        {
                            break;
                        }
                        else
                        {
                            result++;
                        }
                    }

                    long treasure = result;

                    for (long i = 0; i < _timesDivided; i++)
                    {
                        var remainder = treasure % _input;

                        if (remainder != 1)
                        {
                            break;
                        }

                        var share = (treasure - remainder) / _input;

                        if (i == (_timesDivided - 1))
                        {
                            treasure = (treasure - (share * _input));

                            if (treasure == 1)
                                return result;
                        }
                        else
                        {
                            treasure = (treasure - share) - 1;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //log exception here
                return 0;
            }
        }
    }

我相当确定每个数字都必须是素数,所以我也考虑到了这一点。但是,我还没有找到解决这个问题的有效方法。我的数学太弱了

修改

感谢上面提到的视频Fr3d,我现在有了我的CalculateTreasure方法:

private static long CalculateTreasure()
        {
            try
            {
                long result = (long)Math.Pow((double)_input, (double)_timesDivided);

                while (true)
                {
                    result--;

                    while (true)
                    {
                        if (result % _input == 1)
                        {
                            break;
                        }
                        else
                        {
                            result--;
                        }
                    }

                    long treasure = result;

                    for (long i = 0; i < _timesDivided; i++)
                    {
                        var remainder = treasure % _input;

                        if (remainder != 1)
                        {
                            break;
                        }

                        var share = (treasure - remainder) / _input;

                        if (i == (_timesDivided - 1))
                        {
                            treasure = (treasure - (share * _input));

                            if (treasure == 1)
                                return result;
                        }
                        else
                        {
                            treasure = (treasure - share) - 1;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //log exception here
                return 0;
            }
        }

它有很大的改进,但仍然不是100%最佳

1 个答案:

答案 0 :(得分:1)

我想我找到了正确的公式:

using System;
using System.Numerics;

namespace PirateCoins
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = int.Parse(Console.ReadLine());
            Console.WriteLine(GetTreasure(n));
        }
        static BigInteger GetTreasure(int n)
        {
            BigInteger result = BigInteger.Pow(n, n + 1) - (n - 1);
            return result;
        }
    }
}

这是基于给出2 - >的序列。 7,3-&gt; 79,4 - &gt; 1021,5-&gt; 15621。