這幾天上網,看到百度裡面有人問這一道題目,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個結果。說實話,我也沒想到會有這麼多。。。