在CSDN首页看到 Google编程大赛入围赛750分真题 第五组之后,一时手痒,动手用C++做了一个解决方案,写出来接受大家的批评,呵呵。
先贴上代码,
=============================================================================
#pragma warning (disable : 4786)
#include
#include
#include
namespace S3{
const unsigned int MAX_COUNT = 1000000000;
const unsigned int MAX_UINT = 0xFFFFFFFF;
struct cell
{
char ch;
int count[2];
};
class CGrid
{
typedef cell* LPCELL;
public:
CGrid() : m_RowCount(0), m_ColCount(0), m_ppCells(NULL) { }
~CGrid() { Clear(); }
bool Initialize(const std::vector& grid)
{
Clear();
m_RowCount = grid.size();
if (m_RowCount <= 0)
{
return false;
}
m_ColCount = grid[0].size();
if (m_ColCount <= 0)
{
return false;
}
for (int i=0; i {
if (grid[i].size() != m_ColCount)
{
return false;
}
}
int nCount = m_RowCount * m_ColCount;
m_ppCells = new LPCELL[nCount];
if (m_ppCells == NULL)
{
return false;
}
for (i=0; i {
for (int j=0; j {
LPCELL p = new cell;
m_ppCells[i * m_ColCount + j] = p;
p->ch = grid[i][j];
}
}
return true;
}
int CountPath(const std::string& find)
{
int nLen = find.size();
if (nLen <= 0)
{
return 0;
}
const char* sz = find.c_str();
char* pos = (char*)(sz + nLen - 1);
int index = 0;
while (pos >= sz)
{
if (!Calculate(*pos, *(pos+1), index))
{
return -1;
}
pos--;
index++;
}
int sum = 0;
for (int i=0; i {
if (m_ppCells[i]->ch == *sz)
{
int t = m_ppCells[i]->count[(index-1)%2];
if (sum > MAX_COUNT || (MAX_COUNT > sum && MAX_COUNT - sum < t))
{
sum = -1;
break;
}
else
{
sum += t;
}
}
}
return sum;
}
private:
bool Calculate(char c1, char c2, int index)
{
if (c2 == '/0')
{
for (int i=0; i {
if (m_ppCells[i]->ch == c1)
{
m_ppCells[i]->count[index] = 1;
}
}
}
else
{
int seq = (index-1) % 2;
for(int i=0; i {
for (int j=0; j {
LPCELL p = GetCell(i, j);
if (p->ch == c1)
{
unsigned int count = 0;
for (int m=-1; m<=1; m++)
{
for (int n=-1; n<=1; n++)
{
if (m != 0 || n != 0)
{
LPCELL q = GetCell(i+n, j+m);
if (q != NULL && q->ch == c2)
{
if (MAX_UINT - count < q->count[seq])
{
return false;
}
count += q->count[seq];
}
}
}
}
p->count[index%2] = count;
}
}
}
}
return true;
}
LPCELL GetCell(int row, int col)
{
if (row < 0 || col < 0)
{
return NULL;
}
if (row >= m_RowCount || col >= m_ColCount)
{
return NULL;
}
return m_ppCells[row * m_ColCount + col];
}
void Clear()
{
if (m_ppCells != NULL)
{
int nCount = m_RowCount * m_ColCount;
for (int i=0; i {
delete m_ppCells[i];
}
delete[] m_ppCells;
m_ppCells = NULL;
}
m_RowCount = 0;
m_ColCount = 0;
}
private:
int m_RowCount;
int m_ColCount;
LPCELL* m_ppCells;
};
class WordPath
{
private:
WordPath();
public:
static int countPath(const std::vector& grid, const std::string& find)
{
CGrid gd;
gd.Initialize(grid);
return gd.CountPath(find);
}
};
class TestHelp
{
private:
TestHelp();
public:
static void Test(const std::vector& grid, const std::string& find)
{
DisplayParameter(grid, find);
std::cout << "Returns: " << WordPath::countPath(grid, find) << std::endl << std::endl;
}
static void DisplayParameter(const std::vector& grid, const std::string& find)
{
std::cout << "Input grid:" << std::endl;
for (int i=0; i {
std::cout << grid[i].c_str() << std::endl;
}
std::cout << "Find string: " << find.c_str() << std::endl;
}
};
void Test0()
{
std::vector vec;
vec.push_back("ABC");
vec.push_back("FED");
vec.push_back("GHI");
std::string find = "ABCDEFGHI";
TestHelp::Test(vec, find);
}
void Test1()
{
std::vector vec;
vec.push_back("ABC");
vec.push_back("FED");
vec.push_back("GAI");
std::string find = "ABCDEA";
TestHelp::Test(vec, find);
}
void Test2()
{
std::vector vec;
vec.push_back("ABC");
vec.push_back("DEF");
vec.push_back("GHI");
std::string find = "ABCD";
TestHelp::Test(vec, find);
}
void Test3()
{
std::vector vec;
vec.push_back("AA");
vec.push_back("AA");
std::string find = "AAAA";
TestHelp::Test(vec, find);
}
void Test4()
{
std::vector vec;
vec.push_back("ABABA");
vec.push_back("BABAB");
vec.push_back("ABABA");
vec.push_back("BABAB");
vec.push_back("ABABA");
std::string find = "ABABABBA";
TestHelp::Test(vec, find);
}
void Test5()
{
std::vector vec;
vec.push_back("AAAAA");
vec.push_back("AAAAA");
vec.push_back("AAAAA");
vec.push_back("AAAAA");
vec.push_back("AAAAA");
std::string find = "AAAAAAAAAAA";
TestHelp::Test(vec, find);
}
void Test6()
{
std::vector vec;
vec.push_back("AB");
vec.push_back("CD");
std::string find = "AA";
TestHelp::Test(vec, find);
}
void Test()
{
Test0();
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
}
}
int main(int argc, char* argv[])
{
S3::Test();
return 0;
}
=================================================================================
简短的说明一下思路:
算法是倒过查字符,为每个字符加权。
例如在
ABC
FED
GAI
中查找
ABCDEA
首先,得到最后一个字符A,我先把grid中是A的位置标上加权值1,如果不是A可不关心,得到
100
000
010
然后在找E,并计算每个E周围的A的个数,将总个数设置为E的加权,得到
100
020
010
再找D,并计算D周围E的加权之和,得到
100
022
010
依次类推, 最后得到
222
022
000
最后只要计算grid中所有A的加权和即可。