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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值