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

在CSDN首页看到 Google编程大赛入围赛750分真题   第五组之后,一时手痒,动手用C++做了一个解决方案,写出来接受大家的批评,呵呵。

先贴上代码,
=============================================================================

#pragma warning (disable : 4786)

#include <list>
#include <vector>
#include <iostream>

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<std::string>& 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<m_RowCount; 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<m_RowCount; i++)
            {
                for (int j=0; j<m_ColCount; 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<m_RowCount * m_ColCount; 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<m_RowCount*m_ColCount; i++)
                {
                    if (m_ppCells[i]->ch == c1)
                    {
                        m_ppCells[i]->count[index] = 1;
                    }
                }
            }
            else
            {
                int seq = (index-1) % 2;
                for(int i=0; i<m_RowCount; i++)
                {
                    for (int j=0; j<m_ColCount; 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<nCount; 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<std::string>& 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<std::string>& 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<std::string>& grid, const std::string& find)
        {
            std::cout << "Input grid:" << std::endl;
            for (int i=0; i<grid.size(); i++)
            {
                std::cout << grid[i].c_str() << std::endl;
            }
            std::cout << "Find string: " << find.c_str() << std::endl;
        }
    };

    void Test0()
    {
        std::vector<std::string> 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<std::string> 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<std::string> 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<std::string> vec;
        vec.push_back("AA");
        vec.push_back("AA");

        std::string find = "AAAA";
        TestHelp::Test(vec, find);
    }

    void Test4()
    {
        std::vector<std::string> 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<std::string> 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<std::string> 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的加权和即可。

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值