刚才在园子里看到 周利华关于 "有道难题"的两道题的算法,eaglet 做了一下,第一题比周利华的算法快10倍左右,第二天快100倍左右。由于eaglet不符合参赛条件,所以就在博客园和大家交流交流吧。
第一道算法题(250分)
话说你在走路上班时,经过一片种植萝卜的农田。这块田地的形状是一个矩形的网格。field的第i个元素的第j个字符,表示田地的第i 行第j列的格子里包含的萝卜的数目。我们定义一个格子的特殊程度为它周围所有格子的萝卜个数的和; 它周围的格子包含它上下左右以及对角相邻的格子,最多有8个,在田地的边界上的格子会少一些。如果一个格子周围没有别的格子,则它的特殊程度为0。
请返回田地中特殊程度在A和B之间的所有格子的数目(包含A,B)。
Definition
Class: NumberField
Method: countSpecialNumbers
Parameters: string[], int, int
Returns: int
Method signature: int countSpecialNumbers(string[] field, int A, int B)
(be sure your method is public)
Constraints
- field 包含1个到50个元素,含1和50。
- field的每个元素包含1个到50个字符,含1和50。
- field的每个元素包含相同的字符数。
- field的每个元素的字符均为’0’到’9’之一。
- A的范围会在0到100之间,含0和100。
- B 的范围会在A到100之间,含A和100。
Examples
0)
{"111",
"111",
"111"}
4
8
Returns: 5
在这块田地里面,位于角落的格子的特殊程度是3,位于中间的格子的特殊程度是8,其他4个格子的特殊程度为5。
1)
{"111",
"141",
"111"}
4
8
Returns: 9
现在所有的9个格子都满足要求。
2)
{"2309",
"0239",
"2314"}
5
7
Returns: 3
3)
{"924",
"231",
"390",
"910",
"121"}
31
36
Returns: 0
4)
{"5"}
3
8
Returns: 0
5)
{"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890"}
3
18
Returns: 26
下面是eaglet 的算法。
测试代码
测试结果 //重复执行10000次
eaglet 的算法
5
9
3
0
0
26
用时1439毫秒 //0.1439毫秒每次
周利华 的算法
5
9
3
0
0
26
用时18205毫秒
西狐.Net 的算法
5
9
3
0
0
26
用时31902毫秒
第二道算法题(500分)
题目要求:双倍超立方数是指一个正整数可以正好被拆分为两种不同的a^3+b^3的方式,其中a,b均为整数且0<a<=b。对于任何一个指定的 int n, 返回所有的小于等于n的双倍超立方数的个数。
Definition
Class: TwiceSuperCubic
Method: count
Parameters: int
Returns: int
Method signature: int count(int n)
(be sure your method is public)
Constraints
- n取值范围为1到1,000,000,000(含)
Examples
0)
1
Returns: 0
1)
1729
Returns: 1
1729=1^3+12^3
1729=9^3+10^3
2)
475574
Returns: 27
eaglet 的代码
测试代码
测试结果 //重复执行1000次
eaglet 的算法
0
1
27
用时262毫秒 //0.262毫秒每次
周利华 的算法
0
1
27
用时21770毫秒
备注: 由于是算法题,eaglet 对一些参数的检查没有做的很完整,另外没有做线程安全设计,这些已经超出了算法考察的范围,希望大家把讨论的重点放在算法上,eaglet 水平有限,相信园子里像老赵这样的高手应该大把大把的,eaglet热切希望能看到比这个跑的更快的算法出现。