P1032 字串变换(bfs)

https://www.luogu.org/problemnew/show/P1032
题目描述
已知有两个字串A,BA,B及一组字串变换的规则(至多66个规则):

A 1-> B 1
A 2 -> B 2
​	 

规则的含义为:在 A中的子串A 1
​可以变换为 B 1,A 2可以变换为B 2
​ …。

例如:A='abcd'B='xyz'

变换规则为:

‘abc’->‘xu’‘ud’->‘y’‘y’->‘yz’

则此时,A可以经过一系列的变换变为B,其变换的过程为:

‘abcd’->‘xud’->‘xy’->‘xyz’

共进行了3次变换,使得AA变换为BB。

输入输出格式
输入格式:
输入格式如下:

AA BB
A 1 B 1	 
A 2 B 2

|-> 变换规则

… … /

所有字符串长度的上限为20。

输出格式:
输出至屏幕。格式如下:

若在10步(包含10步)以内能将A变换为B,则输出最少的变换步数;否则输出"NO ANSWER!"

输入输出样例
输入样例#1:

abcd xyz
abc xu
ud y
y yz

输出样例#1:

3

ac_code:
/*
每个点是一个字符串,想到用map标记~
之前用dfs做只有60分,然后第一次用bfs做80分,最后组数据WA
WA的点就是,没有考虑到一个串对于一种转换规则可能会有多个位置可变,而他们都是1步到达:
比如:

aacadb   abcdef(原串,目标串)
a  b(其中一条转换规则)
一步就可以得到:
bacadb
abcadb
aacbdb

所以对于原串不是找到一处匹配的就变换后进行下个规则
而是继续对于这个规则找找看一下有没有其他地方可以匹配
so对于查询是否有可以使用转换规则时要用while
还有对于输入,它规则个数是不确定的,可以用ctrl+z结束输入,但是要记录到底用多少条规则
*/

#include <iostream>
#include <string>
#include <queue>
#include <map>
using namespace std;
struct rules
{
    string A;
    string B;
    int len_a;
} data[10];
string s,e;
int cnt;
map<string,bool>vis;
map<string,int>step;
int bfs()
{
    queue<string>q;
    q.push(s);
    vis[s] = true;
    while(!q.empty())
    {
        string k = q.front();
        if(step[k] > 10)
        {
            break;
        }
        q.pop();
        if(k == e)
        {
            return step[k];
        }
        for(int i = 0; i < cnt; i++)
        {
            int pos = -1;
            //string t = k; //如果要直接用replace要先记录下原串
            while(k.find(data[i].A,pos+1)!=string::npos)
            {
                pos = k.find(data[i].A,pos+1);
                //cout<<pos<<endl;
                if(pos != -1)
                {
                    string s1 = k.substr(0,pos);
                    int t = pos + data[i].len_a;
                    string s2 = k.substr(t,k.length()-t);
                    string now = s1 + data[i].B + s2;
                    //string now = k.replace(pos,data[i].len_a,data[i].B);//replace会使原串改变
                    //k = t;
                    //cout<<now<<" "<<k<<endl;
                    if(!vis[now])
                    {
                        vis[now] = true;
                        step[now] = step[k] + 1;
                        q.push(now);
                    }
                }
            }
        }
    }
    return -1;
}
int main()
{
    cin>>s>>e;
    for(int i = 0; i < 6; i++)
    {
        cin>>data[i].A>>data[i].B;
        data[i].len_a = data[i].A.length();
        if(data[i].A == "\0")
            break;
        else cnt++;
    }
    int ans = bfs();
    if(ans != -1)
        cout<<ans<<endl;
    else
        cout<<"NO ANSWER!"<<endl;
    return 0;
}


猜你喜欢

转载自blog.csdn.net/tb_youth/article/details/92388489
今日推荐