【洛谷1032 】【CJOJ1711】【NOIP2002】字串变换

题目描述

已知有两个字串 A, B 及一组字串变换的规则(至多6个规则):

     A1 -> B1

     A2 -> B2

规则的含义为:在 A$中的子串 A1 可以变换为 B1、A2 可以变换为 B2 …。

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

变换规则为:

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

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

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

共进行了三次变换,使得 A 变换为B。

输入格式:

键盘输人文件名。文件格式如下:

A B A1 B1

   A2 B2 |-> 变换规则

... ... /

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

输出格式:

输出至屏幕。格式如下:

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

输入样例#1:

abcd xyz
abc xu
ud y
y yz

输出样例#1:

3

题解

其实这道题目数据并不是很强,

所以直接暴力枚举即可(NOIP良心题目)

(如果数据很强的话是不是要用AC自动机???)

每次枚举当前串

枚举每一种变幻方案

查询是否可行

然后变幻一下,放到队列之中继续广搜

(用广搜是很明显的,因为要求最小步数)

判重可以使用map(C++STL真好用)

而对于变幻后字符串的拼接可以使用string中的substr就会非常方便

其他的细节可以看代码(以后这题可能会更新写法)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
#define MAX 5000
struct Node
{
      string s;
      int st;
};
map<string,int> M;
string A,B,a[MAX],b[MAX];
int n=0;
queue<Node> Q;
int cnt=1;
int main()
{ 
    cin>>A;cin>>B;
    while(cin>>a[++n])
          cin>>b[n];
    n--;
    M[A]=0;
    Q.push((Node){A,0});
    while(!Q.empty())
    {
                 string s=Q.front().s;
                 int St=Q.front().st,l=s.length();
                 if(St==11)break;
                 Q.pop();
                 for(int i=1;i<=n;++i)//检查所有规则
              {
                      int l2=a[i].length();
                      for(int j=0;j<=l-l2;++j)
                      {
                               if(s.substr(j,l2)==a[i])//匹配规则
                             {
                                     string ss;ss.clear();
                                     if(j!=0)ss+=s.substr(0,j);
                                     ss+=b[i];
                                     if(j+l2<l)ss+=s.substr(j+l2,l-l2-j+1);//拼合 
                                     if(M.find(ss)==M.end())//没有被用过 
                                     {
                                            M[ss]=St+1;
                                            Q.push((Node){ss,St+1});
                                     }
                                     if(ss==B)//找到结果 
                                     {
                                            cout<<St+1<<endl;
                                            return 0;
                                     }
                             }
                      }
              }
    }
    cout<<"NO ANSWER!"<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/cjyyb/p/7197291.html