经典算法题每日演练——第二题 五家共井

原文:经典算法题每日演练——第二题 五家共井

古代数学巨著《九章算数》中有这么一道题叫“五家共井,甲二绠(汲水用的井绳)不足,如(接上)乙一绠;乙三绠不足,如丙一绠;

丙四绠不足,如丁一绠;丁五绠不足,如戊一绠;戊六绠不足,如甲一绠,皆及。

意思就是说五家人共用一口井,甲家的绳子用两条不够,还要再用乙家的绳子一条才能打到井水;乙家的绳子用三条不够,还要再用丙家的绳子

一条才能打到井水;丙家的绳子用四条不够,还要再用丁家的绳子一条才能打到井水;丁家的绳子用五条不够,还要再用戊家的绳子一条才能打

到井水;戊家的绳子用六条不够,还要再用甲家的绳子一条才能打到井水。

最后问:井有多深?每家的绳子各有多长?

分析:同样这套题也是属于不定方程,拿这个题目的目地就是让大家能够在不定方程组这种范畴问题上做到“举一反三”,根据题意

我们设井深为h,各家分别为a,b,c,d,e,则可以列出如下方程组:

2a+b=h   ①

3b+c=h   ②

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的倍数,根据这种关系我们

就可以有如下代码:

 1 namespace Test
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             int a, b, c, d, e, h;
 8
 9             a = b = c = d = e = h = 0;
10
11             bool flag = true;
12
13             while (flag)
14             {
15                 //4的倍数
16                 e += 4;
17
18                 a = 0;
19
20                 while (flag)
21                 {
22                     //5的倍数
23                     a += 5;
24
25                     d = e + a / 5;
26
27                     c = d + e / 4;
28
29                     if (c % 2 != 0)
30                         continue;
31
32                     if (d % 3 != 0)
33                         continue;
34
35                     b = c + d / 3;
36
37                     if (b + c / 2 < a)
38                         break;
39
40                     if (b + c / 2 == a)
41                         flag = false;
42                 }
43             }
44
45             h = 2 * a + b;
46
47             Console.WriteLine("a={0},b={1},c={2},d={3},e={4} ------h={5}\n", a, b, c, d, e, h);
48
49             Console.Read();
50         }
51     }
52 }

同样我们的时间复杂度是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,否则绳子已经到达极限了,需要用蛟龙号去深潜了。

 1 namespace Test
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             for (int k = 1; k < 5; k++)
 8             {
 9                 int h = 721 * k;
10
11                 int a = 265 * k;
12
13                 int b = 191 * k;
14
15                 int c = 148 * k;
16
17                 int d = 129 * k;
18
19                 int e = 76 * k;
20
21                 Console.WriteLine("a={0},b={1},c={2},d={3},e={4} ------h={5}\n", a, b, c, d, e, h);
22             }
23
24             Console.Read();
25         }
26     }
27 }

相信大家以后遇到类似的问题,应该会胸有成竹了。

时间: 2024-10-07 18:42:59

经典算法题每日演练——第二题 五家共井的相关文章

经典算法题每日演练——第二十五题 块状链表

原文:经典算法题每日演练--第二十五题 块状链表 在数据结构的世界里,我们会认识各种各样的数据结构,每一种数据结构都能解决相应领域的问题,每一种数据结构都像 是降龙十八掌中的某一掌,掌掌毙命... 当然每个数据结构,有他的优点,必然就有它的缺点,那么如何创造一种数据结构 来将某两种数据结构进行扬长避短,那就非常完美了.这样的数据结构也有很多,比如:双端队列,还有就是今天讲的 块状链表, 我们都知道 数组 具有 O(1)的查询时间,O(N)的删除,O(N)的插入... 链表 具有 O(N)的查询时

经典算法题每日演练——第二十题 三元组

原文:经典算法题每日演练--第二十题 三元组 我们知道矩阵是一个非常强大的数据结构,在动态规划以及各种图论算法上都有广泛的应用,当然矩阵有着不足的地方就是空间和时间 复杂度都维持在N2上,比如1w个数字建立一个矩阵,在内存中会占用1w*1w=1亿的类型空间,这时就会遇到outofmemory...那么面 临的一个问题就是如何来压缩矩阵,当然压缩的方式有很多种,这里就介绍一个顺序表的压缩方式:三元组. 一:三元组 有时候我们的矩阵中只有零星的一些非零元素,其余的都是零元素,那么我们称之为稀疏矩阵,

经典算法题每日演练——第二十四题 梳排序

原文:经典算法题每日演练--第二十四题 梳排序 这篇再看看一个经典的排序,梳排序,为什么取名为梳,可能每个梳都有自己的gap吧,大梳子gap大一点,小梳子gap小一点. 上一篇我们看到鸡尾酒排序是在冒泡排序上做了一些优化,将单向的比较变成了双向,同样这里的梳排序也是在冒泡排序上做了一些优化. 冒泡排序上我们的选择是相邻的两个数做比较,就是他们的gap为1,其实梳排序提出了不同的观点,如果将这里的gap设置为一定的大小, 效率反而必gap=1要高效的多. 下面我们看看具体思想,梳排序有这样一个1.

经典算法题每日演练——第二十二题 奇偶排序

原文:经典算法题每日演练--第二十二题 奇偶排序 这个专题因为各种原因好久没有继续下去了,MM吧...你懂的,嘿嘿,不过还得继续写下去,好长时间不写,有些东西有点生疏了, 这篇就从简单一点的一个“奇偶排序”说起吧,不过这个排序还是蛮有意思的,严格来说复杂度是O(N2),不过在多核的情况下,可以做到 N2 /(m/2)的效率,这里的m就是待排序的个数,当m=100,复杂度为N2 /50,还行把,比冒泡要好点,因为重点是解决问题的奇思妙想. 下面我们看看这个算法是怎么描述的,既然是奇偶,肯定跟位数有

经典算法题每日演练——第二十一题 十字链表

原文:经典算法题每日演练--第二十一题 十字链表 上一篇我们看了矩阵的顺序存储,这篇我们再看看一种链式存储方法“十字链表”,当然目的都是一样,压缩空间. 一:概念 既然要用链表节点来模拟矩阵中的非零元素,肯定需要如下5个元素(row,col,val,down,right),其中: row:矩阵中的行. col:矩阵中的列. val:矩阵中的值. right:指向右侧的一个非零元素. down:指向下侧的一个非零元素. 现在我们知道单个节点该如何表示了,那么矩阵中同行的非零元素的表示不就是一个单链

经典算法题每日演练——第十五题 并查集

原文:经典算法题每日演练--第十五题 并查集 这一篇我们看看经典又神奇的并查集,顾名思义就是并起来查,可用于处理一些不相交集合的秒杀. 一:场景 有时候我们会遇到这样的场景,比如:M={1,4,6,8},N={2,4,5,7},我的需求就是判断{1,2}是否属于同一个集合,当然实现方法 有很多,一般情况下,普通青年会做出O(MN)的复杂度,那么有没有更轻量级的复杂度呢?嘿嘿,并查集就是用来解决这个问题的. 二:操作 从名字可以出来,并查集其实只有两种操作,并(Union)和查(Find),并查集

经典算法题每日演练——第二十三题 鸡尾酒排序

原文:经典算法题每日演练--第二十三题 鸡尾酒排序 这篇我们继续扯淡一下鸡尾酒排序,为了知道为啥取名为鸡尾酒,特意看了下百科,见框框的话,也只能勉强这么说了. 要是文艺点的话,可以说是搅拌排序,通俗易懂点的话,就叫“双向冒泡排序”,我想作为码农的话,不可能不知道冒泡排序, 冒泡是一个单向的从小到大或者从大到小的交换排序,而鸡尾酒排序是双向的,从一端进行从小到大排序,从另一端进行从大 到小排序. 从图中可以看到,第一次正向比较,我们找到了最大值9. 第一次反向比较,我们找到了最小值1. 第二次正向

经典算法题每日演练——第九题 优先队列

原文:经典算法题每日演练--第九题 优先队列 前端时间玩小爬虫的时候,我把url都是放在内存队列里面的,有时我们在抓取url的时候,通过LCS之类的相似度比较,发现某些url是很重要的, 需要后端解析服务器优先处理,针对这种优先级比较大的url,普通的队列还是苦逼的在做FIFO操作,现在我们的需求就是优先级大的优先服务,要做 优先队列,非堆莫属. 一:堆结构 1:性质 堆是一种很松散的序结构树,只保存了父节点和孩子节点的大小关系,并不规定左右孩子的大小,不像排序树那样严格,又因为堆是一种完全二叉

经典算法题每日演练——第一题 百钱买百鸡

原文:经典算法题每日演练--第一题 百钱买百鸡 百钱买百鸡的问题算是一套非常经典的不定方程的问题,题目很简单:公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱, 用100文钱买一百只鸡,其中公鸡,母鸡,小鸡都必须要有,问公鸡,母鸡,小鸡要买多少只刚好凑足100文钱. 分析:估计现在小学生都能手工推算这套题,只不过我们用计算机来推算,我们可以设公鸡为x,母鸡为y,小鸡为z,那么我们 可以得出如下的不定方程, x+y+z=100, 5x+3y+z/3=100, 下面再看看x,y,z的取值范围. 由于只