Google编程大赛入围赛750分真题(第五组) 之解法

在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的加权和即可。

你可能感兴趣的:(C,&,C++)