zoukankan      html  css  js  c++  java
  • 【洛谷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;
    }
    
  • 相关阅读:
    [置顶] 搭建一个流媒体服务器引子
    Exchange Server 2007 常见问题解答(6)
    [置顶] 第九周项目1
    iOS 6应用开发实战
    hdu 1722(数论)
    js二维数组排序
    HDU 4027 线段树 Can you answer these queries?
    Socket编程指南及示例程序
    Spring攻略学习笔记(2.13)解析文本消息
    线性渐变lineargradient和滤镜opacity/filter的透明效果兼容性解决方案及其RGB/RGBA与16进制转换方法
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7197291.html
Copyright © 2011-2022 走看看