摘要
昨天,由于比赛严禁在5月31日当天通过任何渠道传播、讨论题目、解答方法和程序。网易“有道难题”打电话,特别声明,让我暂时删掉关于这两道算法的随笔,哈哈,吓我一跳,我差点泄题,不过遵循她意见后,将昨天的帖子删掉,改到今天拿出来一起切磋一下。程序竞赛之所以吸引众多编程爱好者,是因为可以再互相学习、切磋提高。:)
第一道算法题(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
以下是我实现的用一个方法搞定的代码:
C#代码实现一
/// <summary>
/// 萝卜地
/// </summary>
/// <param name="field">矩阵</param>
/// <param name="A">范围A</param>
/// <param name="B">范围B</param>
/// <returns></returns>
/// <author>周利华(http://www.zivsoft.com)</author>
public int countSpecialNumbers(string[] field, int A, int B)
{
int i = 0, j = 0, result = 0, v = 0;
if (field == null || field.Length == 0) return result;//无方格
int xLen = field.Length, yLen = field[0].Length;//列,行长度
for (i = 0; i < xLen; i++)
{
for (j = 0; j < yLen; j++)
{
if (i + 1 < xLen && j - 1 > -1) v += Convert.ToInt32(field[i + 1][j - 1].ToString());//右上
if (i + 1 < xLen) v += Convert.ToInt32(field[i + 1][j].ToString());//右中
if (i + 1 < xLen && j + 1 < yLen) v += Convert.ToInt32(field[i + 1][j + 1].ToString());//右下
if (i - 1 > -1 && j - 1 > -1) v += Convert.ToInt32(field[i - 1][j - 1].ToString());//左上
if (i - 1 > -1) v += Convert.ToInt32(field[i - 1][j].ToString());//左中
if (i - 1 > -1 && j + 1 < yLen) v += Convert.ToInt32(field[i - 1][j + 1].ToString());//左下
if (j - 1 > -1) v += Convert.ToInt32(field[i][j - 1].ToString());//中上
if (j + 1 < yLen) v += Convert.ToInt32(field[i][j + 1].ToString());//中下
if ((v > A || v == A) && (v == B || v < B)) result++;//找到一个满足要求的答案
v = 0;//清零
}
}
return result;
}
下面的实现由西狐.Net提供,原文:http://www.cnblogs.com/hooyes/archive/2009/06/01/radish.html
C#代码实现二
/// <summary>
/// 获取第i,j格的萝卜数
/// </summary>
/// <param name="i">行</param>
/// <param name="j">列</param>
/// <param name="field"></param>
/// <returns></returns>
private int GetRadishNumber(int i, int j, string[] field)
{
if (i < 0 || j < 0) return 0;
if ((i > field.Length-1) || (j > field[0].Length-1)) return 0;
return Convert.ToInt32(((char)Encoding.ASCII.GetBytes(field[i])[j]).ToString());
}
/// <summary>
/// 获取第i,j格的特殊程度
/// </summary>
/// <param name="i">行</param>
/// <param name="j">列</param>
/// <param name="field">矩阵</param>
/// <returns></returns>
private int GetSpecialValue(int i, int j, string[] field)
{
return GetRadishNumber(i - 1, j, field) + GetRadishNumber(i + 1, j, field) + GetRadishNumber(i, j - 1, field) + GetRadishNumber(i, j + 1, field) + GetRadishNumber(i - 1, j - 1, field) + GetRadishNumber(i + 1, j + 1, field) + GetRadishNumber(i - 1, j + 1, field) + GetRadishNumber(i + 1, j - 1, field);
}
/// <summary>
/// 返回满足特殊度在A至B之间的格子数
/// </summary>
/// <param name="field"></param>
/// <param name="A">特殊度下限</param>
/// <param name="B">特殊度上限</param>
/// <returns></returns>
public int countSpecialNumbers(string[] field, int A, int B)
{
int iResult = 0;
if (field == null || field.Length == 0) return iResult;
int y = field.Length - 1; //行
int x = field[0].Length - 1; //列
for (int i = 0; i <= y; i++)
{
for (int j = 0; j <= x; j++)
{
int tInt = GetSpecialValue(i, j, field);
if (tInt >= A && tInt <= B)
{
iResult++;
}
}
}
return iResult;
}
对于题目一,做完后,总感觉这是不是在考“动态规划”的算法思想?虽然如此,但我个人认为是不是需要考虑动态规划的方法来优化,感觉有重复的计算“特殊程度”。但由于只是读数据,所以没做动态规划方面的修改。:-)
第二道算法题(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
C#代码实现
public int count(int n)
{
int a, b;
int up = (int)Math.Pow((double)n / 2, 1f / 3);
int down = (int)Math.Pow((double)n, 1f / 3);
int count = 0;
int[][] matrix=new int[up+1][];
for (int i = 1; i <= up; i++)
{
matrix[i] = new int[down + 1];
}
for (a = 1; a <= up; a++)
{
for (b = a; b <= down; b++)
{
matrix[a][b] = a * a * a + b * b * b;
}
}
for (a = 1; a < up; a++)
{
for (b = a; b <= down; b++)
{
for (int c = a + 1; c <= up; c++)
{
for (int d = c; d <= down; d++)
{
if (matrix[a][b] == matrix[c][d] && matrix[a][b] <= n) count++;
else if (matrix[a][b] < matrix[c][d]) break;
}
}
}
}
return count;
}
作者:周利华
出处:http://www.cnblogs.com/architect/archive/2009/06/01/1493519.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。