洛谷P1032-子串变换 广搜和STL

题目大意是给定原始字符串A和目标字符串B
并提供一些子串的提供方案,如果串中存在某个子串a,则可以将其替换为子串b。
求解的问题是至少经过多少次子串替换可以让A变换到B,如果替换次数超过10次或者不能变换到B,则表示问题无解。

例如输入:
abcd xyz
abc xu
ud y
y yz
输出为3
表示abcd经过3次子串替换后可以得到xyz。

这个题很显然是一个广搜题,因为要求最少次数。问题的关键在于这个字符串的替换让人觉得有点不舒服,那么采用STL中的String中的方法就可以较为简便地完成。
string中的substr方法可以有效地完成字符串的截取任务,find方法可以便捷地查询字符串中包含某个子串的位置。
搜索的过程中注意剪枝,不然会超时。用一个map,记录每次替换后的得到的字符串对应的总操作次数。当经过某次替换后出现map中存在的字符串的时候,就是重复,这个时候需要剪枝。

#include<string>
#include <vector>
#include <map>
#include <queue>
#include <iostream>
using namespace std;

struct node
{
    string str;
    int step;
};

vector<pair<string, string>> replaceTable;
map<string, int> searchTable;
string from, to;

void bfs()
{
    node start;
    start.str = from;
    start.step = 0;
    queue<node> nodeQue;
    nodeQue.push(start);
    while (!nodeQue.empty())
    {
        node cur = nodeQue.front();
        nodeQue.pop();
        if (cur.step > 10 )
        {
            cout << "NO ANSWER!" << endl;
            return;
        }
        if (cur.str == to)
        {
            cout << cur.step << endl;;
            return;
        }
        for (auto replacePair : replaceTable)
        {
            int pos = cur.str.find(replacePair.first);
            while (pos!=cur.str.npos)
            {
                string newStr = cur.str.substr(0, pos);
                newStr += replacePair.second;
                newStr += cur.str.substr(pos+replacePair.first.size());
                if (!searchTable[newStr] || searchTable[newStr] > cur.step + 1)
                {
                    node newNode;
                    newNode.step = cur.step + 1;
                    newNode.str = newStr;
                    searchTable[newStr] = cur.step + 1;
                    nodeQue.push(newNode);
                }
                pos = cur.str.find(replacePair.first, pos + 1);
            }
        }
    }
    cout << "NO ANSWER!" << endl;

}

int main()
{
    cin >> from >> to;
    string a, b; 
    while (cin >> a >> b)
    {
        replaceTable.push_back(pair<string, string>(a, b));
    }
    bfs();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yjr3426619/article/details/81604453