zoukankan      html  css  js  c++  java
  • [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!"

    [输入样例]

    abcd xyz
    abc xu
    ud y
    y yz
    

    [输出样例]

    3

    solution

    不能用dfs,要用bfs,而且是双向bfs,用map<string,int>来记录当前串出现时走的步数以及是否出现

    剪枝:如果此串已出现过,则不用再push如队列

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<string>
      5 #include<queue>
      6 #include<map>
      7 using namespace std;
      8 const int N=301;
      9 int minn(int a,int b){return a<b?a:b;}
     10 
     11 struct son
     12 {
     13     string s;
     14     int bushu;
     15     son(string qq,int ww)
     16     {
     17         s=qq;bushu=ww;
     18     }
     19 };
     20 int cnt,ans=1000;
     21 string a,b,a1[8],b1[8];
     22 map<string,int> mpa,mpb;
     23 queue<son> qa,qb;
     24 
     25 int fin(string a,int pos,string s,int lena,int lens)
     26 {
     27     for(int i=pos;i<lena-lens+1;++i)
     28         if(a[i]==s[i-pos])
     29         {
     30             int flag=0;
     31             for(int j=0;j<lens;++j)
     32               if(s[j]!=s[j+i])
     33               {flag=1;break;}
     34             if(flag)continue;
     35             return i;
     36         }
     37     return -1;
     38 }
     39 
     40 int bfs()
     41 {
     42     mpa[a]=0;mpb[b]=0;
     43     qa.push(son(a,0));qb.push(son(b,0));
     44     string temp;
     45     while(!qa.empty()&&!qb.empty())
     46     {
     47         son now=qa.front();qa.pop();
     48         string s=now.s;
     49         
     50         //cout<<s<<endl;
     51         if(now.bushu<=10)
     52         {
     53             if(mpb.count(s))
     54                 ans=minn(ans,mpb[s]+now.bushu);
     55             int len=s.size();
     56             for(int i=1;i<=cnt;++i)
     57             {
     58                 int lent=a1[i].size();
     59               for(int j=0;j<len-lent+1;++j)
     60               {
     61                     if(s.find(a1[i],j)==string::npos)break;
     62                     j=s.find(a1[i],j);
     63                     temp=s;
     64                     s.replace(j,lent,b1[i]);
     65                     //printf("pushas= ");
     66                     //cout<<s<<endl;
     67                     if(!mpa.count(s))
     68                     {
     69                         mpa[s]=now.bushu+1;
     70                         qa.push(son(s,now.bushu+1));
     71                     }
     72                     s=temp;
     73                 }
     74             }
     75         }
     76             
     77         now=qb.front();qb.pop();
     78         s=now.s;
     79         
     80         //cout<<s<<endl;
     81         
     82         if(now.bushu<=10)
     83         {
     84             if(mpa.count(s))
     85                 ans=minn(ans,mpa[s]+now.bushu);
     86             int len=s.size();
     87             for(int i=1;i<=cnt;++i)
     88             {
     89                 int lent=b1[i].size();
     90               for(int j=0;j<len-lent+1;++j)
     91               {
     92                     /*int pos=fin(s,j,b1[i],len,lent);
     93                     if(pos==-1)break;*/
     94                     if(s.find(b1[i],j)==string::npos)break;
     95                     j=s.find(b1[i],j);
     96                     temp=s;
     97                     //printf("pos=%d lent=%d
    ",pos,lent);
     98                     //cout<<a1[i]<<endl;
     99                     //cout<<s<<endl;
    100                     s.replace(j,lent,a1[i]);
    101                     //cout<<s<<endl;
    102                     //printf("pushbs= ");
    103                     ///cout<<s<<endl;
    104                     if(!mpb.count(s))
    105                     {
    106                         mpb[s]=now.bushu+1;
    107                         qb.push(son(s,now.bushu+1));
    108                     }
    109                     s=temp;
    110                 }
    111             }
    112         }
    113         
    114     }
    115     if(ans<=10)return 1;
    116     return 0;
    117 }
    118 
    119 int main(){
    120     //freopen("1.txt","r",stdin);
    121     //freopen("string.in","r",stdin);
    122     //freopen("string.out","w",stdout);
    123     
    124     cin>>a>>b;
    125     ++cnt;
    126     while(cin>>a1[cnt])
    127     {
    128         cin>>b1[cnt];
    129         ++cnt;
    130     }
    131     --cnt;
    132     
    133     //printf("cnt=%d
    ",cnt);
    134     
    135     if(bfs())
    136       printf("%d",ans);
    137     else
    138       printf("NO ANSWER!");
    139     //while(1);
    140     return 0;
    141 }
    code
  • 相关阅读:
    下午不想写代码了,写个shelve的模块使用(简单实用的小型数据库)。
    io,pickle,json,一把梭哈,把这三个模块都讲了。
    import 和 __import__的区别
    namedtuple工厂函数,创造一个像实例对象的元祖(感觉到了Python的奇妙与可爱之处)。
    写一下base64字节码转换工具。
    Python加密模块的hashlib,hmac模块介绍。
    简述Orderdict,defaultdcit,ChainMap以及MappingProxyType
    工作中碰到的小问题,如何对列表内的字典排序,以及operator.itemgetter介绍。
    最近在写一个虚拟币搬砖脚本,几条建议备注下。
    Python的re,正则表达式,希望这次比较能让我记住里面的80%以上。(未完成,待继续)
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7327739.html
Copyright © 2011-2022 走看看