0~9十個數,每個數只能使用一次,組成兩個三位數相加和為四位數的算法


  這幾天上網,看到百度里面有人問這一道題目,0~9十個數,組成如下加法式 *** + *** = ****,每個數字都只能使用一次,問一共多少中組合?

今天,就用C#語言來寫一下,解出這道題,其他語言算法相同,只是語法不同,這里由於時間關系,不再貼出代碼。

  針對大家提出的優化建議,已經將優化方案寫出,下面是具體優化方案:

  這里先講解一下思路,首先我們是程序員,不是數學家,我們是站在編程的角度思考問題。這里是兩個三位數相加,得到一個四位數,所有數字不能重復,最大的和應該為987 + 654 = 1641,就是說兩個三位數相加的結果不會超過2000.那么1一定在后面的四位數中, 那么最小的三位數是203,最大的三位數是987,確定循環的范圍,當然你非要用100到999也可以,不過就是效率低一些罷了。

  通過循環,得到兩個三位數后,然后就是將兩個數相加,得到他們的和,驗證和是否為四位數、是否重復使用了數字。當然這兩個可以放到一起驗證,我的思路是,將兩個三位數和他們的和,拼成一個字符串,然后判斷0~9哪個數字不存在字符串中,只要有一個不存在,就不符合條件,只有0~9都存在,才是正確結果。

  下面用代碼來實現一下,打開VS2010,新建一個控制台程序,打開Program.cs開始編寫代碼,全部代碼如下:

  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestConsoleApp
{
   class Program
   {
      static void Main(string[] args)
      {
         long start = DateTime.Now.Ticks;
         //實例化PrintNum類
         PrintNum pNum = new PrintNum();
         pNum.printNumbers();
         long useTime = DateTime.Now.Ticks - start;
         Console.WriteLine("Time used:" + useTime / 10000 + "ms");
         Console.Read();
      }
   }

   public class PrintNum
   {
      
      public void printNumbers()
      {
         int result = 0;
         int lineNum = 1;
         for (int i = 203; i <= 987; i++)
         {
            for (int j = 203; j <= 987; j++)
            {
               result = i + j;
               if (isTrue(result, i, j))
               {
                  Console.Write(lineNum.ToString("00") + ": ");
                  Console.Write(i + " + ");
                  Console.Write(j + " = ");
                  Console.Write(result + "\t");
                  //每行顯示三個
                  if (lineNum % 3 == 0)
                  {
                     Console.WriteLine();
                  }
                  lineNum++;
               }
            }
         }
      }
  
        public bool isTrue(int result,int i,int j)
        {  
            String str = "0123456789";  
            String s = result + "" + i + "" + j;  

            for(int k = 0;k < str.Length;k++)
            {
               if (!s.Contains(str[k]))
               {
                  return false;
               }
            }

            return true;  
         }  
   }
}

 

這里寫了一個PrintNum類,將方法封裝到類里面,然后在main方法中實例化該類,調用方法輸出結果。結果如下:

 

這是常規寫法,代碼沒有經過優化,看到執行這個過程一共消耗了474ms.下面是經過優化的代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestConsoleApp
{
   class Program
   {
      static void Main(string[] args)
      {
         long start = DateTime.Now.Ticks;
         //實例化PrintNum類
         PrintNum pNum = new PrintNum();
         pNum.printNumbers();
         long useTime = DateTime.Now.Ticks - start;
         Console.WriteLine("Time used:" + useTime / 10000 + "ms");
         Console.Read();
      }
   }

   public class PrintNum
   {
      public void printNumbers()
      {
         int result = 0;
         int lineNum = 1;
         for (int i = 203; i <= 987; i++)
         {
            for (int j = 987; j >= 203; j--)
            {
               result = i + j;
        
if (result > 1000) { if (isTrue(result, i, j)) { Console.Write(lineNum.ToString("00") + ": "); Console.Write(i + " + "); Console.Write(j + " = "); Console.Write(result + "\t"); //每行顯示三個 if (lineNum % 3 == 0) { Console.WriteLine(); } lineNum++; } } else { break; } } } } public bool isTrue(int result,int i,int j) { String str = "0123456789"; String s = result + "" + i + "" + j; for(int k = 0;k < str.Length;k++) { if (!s.Contains(str[k])) { return false; } } return true; } } }

 

執行結果如圖:

執行共耗時315ms,一下減少了100多毫秒,當然我的電腦性能好,在性能差一點的電腦上面,差別就不是這么多了。優化的思路是,內循環從大到小,當兩個數相加小於1000及不是四位數時,退出本次循環。就是減少了循環次數。

是的,你沒看錯,前面的是序號,一共96個結果。說實話,我也沒想到會有這么多。。。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM