昨天在TopCoder上做了Google Code Jam China 2005的考题。虽然题都不是太难,毕竟才是海选哈,题目类型一个是排列组合类问题,一个是搜索类问题。不过要在1小时内调试并提交两个算法题的代码,对于我这样离开学校工作了几年的人,还是挺不容易的。结果只完成了一道题,没有了继续参加后续比赛的资格。
昨天在TopCoder上做了Google Code Jam China 2005的考题。虽然题都不是太难,毕竟才是海选哈,题目类型一个是排列组合类问题,一个是搜索类问题。不过要在1小时内调试并提交两个算法题的代码,对于我这样离开学校工作了几年的人,还是挺不容易的。结果只完成了一道题,没有了继续参加后续比赛的资格
。
由于TopCoder严厉声明不能私自转载它的考题,那么我贴出我自己做的试题的答案应该没有什么问题吧?下面这是750 Points那个搜索问题的C#版代码:
namespace CodeJam


{
class Program

{
static void Main(string[] args)

{
WordPath wp = new WordPath();
System.DateTime dt = System.DateTime.Now;

string[] grid = new string[]
{ "ABABA", "BABAB", "ABABA", "BABAB", "ABABA" };
int count = wp.countPaths(grid, "ABABABABABABAB");
System.Console.WriteLine(count.ToString("N") + "\r\nElapsed Time: "
+ (System.DateTime.Now - dt).TotalMilliseconds);
System.Console.Read();
}
}

public class WordPath

{
public int countPaths(string[] grid, string find)

{
int pathCount=0;
for ( int i=0 ; i < grid.Length ; ++i )

{
for ( int j=0 ; j < grid.Length ; ++j )

{
if ( grid[i][j] == find[0] )

{
pathCount += GetCanGot(grid, j, i, find, 1);
}
}
}
if ( pathCount > 1000000000 )

{
return -1;
}
return pathCount;
}

public int GetCanGot(string[] strGrid, int x, int y, string find, int index)

{
int cnt = 0;
char ch = find[index];
int len = strGrid.Length;
if ( x >= 1 && strGrid[y][x-1] == ch )

{
if ( index == find.Length-1 ) cnt++;
else cnt += GetCanGot(strGrid, x-1, y, find, index+1);
}
if ( x+1 < len && strGrid[y][x+1] == ch )

{
if ( index == find.Length-1 ) cnt++;
else cnt += GetCanGot(strGrid, x+1, y, find, index+1);
}
if ( y >= 1 && strGrid[y-1][x] == ch )

{
if ( index == find.Length-1 ) cnt++;
else cnt += GetCanGot(strGrid, x, y-1, find, index+1);
}
if ( y+1 < len && strGrid[y+1][x] == ch )

{
if ( index == find.Length-1 ) cnt++;
else cnt += GetCanGot(strGrid, x, y+1, find, index+1);
}
if ( x >= 1 && y >= 1 && strGrid[y-1][x-1] == ch )

{
if ( index == find.Length-1 ) cnt++;
else cnt += GetCanGot(strGrid, x-1, y-1, find, index+1);
}
if ( x >= 1 && y+1 < len && strGrid[y+1][x-1] == ch )

{
if ( index == find.Length-1 ) cnt++;
else cnt += GetCanGot(strGrid, x-1, y+1, find, index+1);
}
if ( x+1 < len && y >= 1 && strGrid[y-1][x+1] == ch )

{
if ( index == find.Length-1 ) cnt++;
else cnt += GetCanGot(strGrid, x+1, y-1, find, index+1);
}
if ( x+1 < len && y+1 < len && strGrid[y+1][x+1] == ch )

{
if ( index == find.Length-1 ) cnt++;
else cnt += GetCanGot(strGrid, x+1, y+1, find, index+1);
}
return cnt;
}
}
} 这个题开始被题目搞得有点郁闷,也就是被它的sample input误导了一下,它的那个4*3*3*3那个示例太迷惑人了:(。上面这个解法在google 1G个路径搜索限制下,在P4 2.4的机器上,最大需要大约40s的运行时间,这样的Performance似乎太磕碜了。
于是后来又用C++写了一遍,效率也没有什么提高,而且比C#版还略微底些
:
// CodingCpp.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include "string.h"
#include <windows.h>

char ** g_Grid;
char * g_Find;
size_t g_Order;
size_t g_FindLength;

int g_OffsetX[] =
{1, 1, 0, -1, -1, -1, 0, 1};

int g_OffsetY[] =
{0, -1, -1, -1, 0, 1, 1, 1};

int getCanGot(int curX, int curY, int index)


{
int tmpX, tmpY, cnt = 0;
for ( int k=0 ; k < 8 ; ++k )

{
tmpX = curX + g_OffsetX[k], tmpY = curY + g_OffsetY[k];
if ( tmpX >= 0 && tmpX < g_Order && tmpY >= 0 && tmpY < g_Order
&& (*(g_Grid[tmpX]+tmpY)) == *(g_Find+index) )

{
if ( index == g_FindLength-1 ) cnt++;
else cnt += getCanGot(tmpX, tmpY, index+1);
}
}
return cnt;
}

int countPaths(char * grid[], char * find)


{
g_Grid = grid;
g_Find = find;
g_Order = strlen(*grid);
g_FindLength = strlen(find);
int count = 0;
for ( size_t i=0 ; i < g_Order ; ++i )

{
for ( size_t j=0 ; j < g_Order ; ++j )

{
if ( *(grid[j]+i) == *find )

{
count += getCanGot(j, i, 1);
}
}
}
return count;
}

int _tmain(int argc, _TCHAR* argv[])


{

char * grid[] =
{"ABABA", "BABAB", "ABABA", "BABAB", "ABABA"};
char * find = "ABABABABABABAB";
int tick = GetTickCount();
size_t count = countPaths(grid, find);
printf("%d\n", count);
printf("%d\n", GetTickCount()-tick);
getchar();
return 0;
} 上面代码中的示例有111,478,680个paths,C#版和C++版分别耗时:2671.875ms和4281ms
。虽然代码逻辑稍有不同,不过这个差别也确实让人大跌眼镜wa。
硬件:P4 2.4G 512M
软件:WinXP SP2, VS.NET 2005
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器