古代數學鉅著《九章算數》中有這麼一道題叫「五家共井,甲二綆(汲水用的井繩)不足,如(接上)乙一綆;乙三綆不足,如丙一綆;html
丙四綆不足,如丁一綆;丁五綆不足,如戊一綆;戊六綆不足,如甲一綆,皆及。優化
意思就是說五家人共用一口井,甲家的繩子用兩條不夠,還要再用乙家的繩子一條才能打到井水;乙家的繩子用三條不夠,還要再用丙家的繩子spa
一條才能打到井水;丙家的繩子用四條不夠,還要再用丁家的繩子一條才能打到井水;丁家的繩子用五條不夠,還要再用戊家的繩子一條才能打3d
到井水;戊家的繩子用六條不夠,還要再用甲家的繩子一條才能打到井水。code
最後問:井有多深?每家的繩子各有多長?htm
分析:一樣這套題也是屬於不定方程,拿這個題目的目地就是讓你們可以在不定方程組這種範疇問題上作到「觸類旁通」,根據題意blog
咱們設井深爲h,各家分別爲a,b,c,d,e,則能夠列出以下方程組:get
2a+b=h ①數學
3b+c=h ②string
4c+d=h ③
5d+e=h ④
6e+a=h ⑤
首先咱們看下普通青年的想法,他們的想法是找a,b,c,d,e之間的對應關係。
依次將②代入①,③代入②,④代入③,⑤代入④可得以下方程組:
a=b+c/2
b=c+d/3
c=d+e/4
d=e+a/5
從計算機的角度來講,我不但願有小數的出現,因此我可推斷: c必定是2的倍數,d必定是3的倍數,e必定是4的倍數,a必定是5的倍數,根據這種關係咱們
就能夠有以下代碼:
namespace Test { class Program { static void Main(string[] args) { int a, b, c, d, e, h; a = b = c = d = e = h = 0; bool flag = true; while (flag) { //4的倍數 e += 4; a = 0; while (flag) { //5的倍數 a += 5; d = e + a / 5; c = d + e / 4; if (c % 2 != 0) continue; if (d % 3 != 0) continue; b = c + d / 3; if (b + c / 2 < a) break; if (b + c / 2 == a) flag = false; } } h = 2 * a + b; Console.WriteLine("a={0},b={1},c={2},d={3},e={4} ------h={5}\n", a, b, c, d, e, h); Console.Read(); } } }
一樣咱們的時間複雜度是O(N2),急需優化。
咱們再來看看文藝青年的想法,他們的想法是找a,b,c,d,e中的某個數與h的對應關係。
好比我就找c與h的對應關係,上面的①②③④⑤可寫成以下方程組:
b=h-2a ⑥
c=h-3b ⑦
d=h-4c ⑧
e=h-5d ⑨
a=h-6e ⑩
將⑥,⑧,⑨,⑩分別代入⑦,一陣痙攣後可知:
c=(148/721)h
上面的公式也就代表了c和h的比例關係,咱們令 h=721k,則 c=148k,將其代入⑥,⑦,⑧,⑨,⑩可得以下方程組
a=265k
b=191k
c=148k
d=129k
e=76k
x=721k
又由於k>0,因此題目有無數個解。這裏我就取0<k<5,不然繩子已經到達極限了,須要用蛟龍號去深潛了。
namespace Test { class Program { static void Main(string[] args) { for (int k = 1; k < 5; k++) { int h = 721 * k; int a = 265 * k; int b = 191 * k; int c = 148 * k; int d = 129 * k; int e = 76 * k; Console.WriteLine("a={0},b={1},c={2},d={3},e={4} ------h={5}\n", a, b, c, d, e, h); } Console.Read(); } } }
相信你們之後遇到相似的問題,應該會成竹在胸了。
出處:http://www.cnblogs.com/huangxincheng/archive/2012/08/06/2625427.html