OIIIIIIII

「NOIP2002」「Codevs1099」 字串变换(BFS

 

1099 字串变换

2002年NOIP全国联赛提高组

时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
 
题目描述 Description

已知有两个字串 $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$。

输入描述 Input Description

输入格式如下:

   $A$ $B$
   $A1$ $B1$ \
   $A2$ $B2$  |-> 变换规则
   ... ... / 
  所有字符串长度的上限为 20。

输出描述 Output Description

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

样例输入 Sample Input

abcd xyz
abc xu
ud y
y yz

样例输出 Sample Output

3

数据范围及提示 Data Size & Hint

hehe 


题解

教材(来自Luogu的题解

这种字符串变换都是考STL的使用啊!!!QAQ

前置知识:

1.map入门:

定义:
    map<type1,type2>mp;
    相当于一个用type1当下标的数组。
 eg:
    map<double,int>mp;
    mp[2.6]=3;
    cout<<mp[2.6];
    //输出3

查找:
直接向数组一样访问就行了,但是要先问一下是否存在。
if(mp.find(x)==mp.end())表示这个下标没有存过。

然后map的各种操作应该(应该?)都是O(log)的。

2.string相关:

定义:
    string a;
    //可以定义字符串数组

访问其中下标为i的字母:
    int k=a[i];
    //注意是从0开始排的

在string a里面找子串b
    int pos=a.find(b);
    //如果存在子串b 返回b的第一个字符对应在a里面的下标(若有多个匹配,返回第一个匹配的下标) 否则返回-1

(划重点)
把string a从pos开始长l的字符整体换成字串b
    a.replace(pos,l+1,b);
    //stl的区间都是左开右闭的

然后就可以乱搞了,BFS一下就星。

这个st.replace可以再神奇一点吗?!!!!!

 1 /*
 2     qwerta
 3     P1032 字串变换
 4     Accepted
 5     100
 6     代码 C++,1.14KB
 7     提交时间 2018-09-26 19:13:29
 8     耗时/内存
 9     26ms, 1432KB
10 */
11 #include<iostream>
12 #include<cstring>
13 #include<cstdio>
14 #include<queue>
15 #include<map>
16 using namespace std;
17 string a[13],b[13];
18 string ma,mb;
19 queue<string>qs;//存字符串
20 queue<int>qn;//存对应的转换次数
21 int n=1;
22 map<string,int>m;
23 int bfs()
24 {
25     qs.push(ma);//push初始状态
26     qn.push(0);
27     while(!qs.empty()&&qn.front()<10)//如果有的搜并且次数不超过10
28     {
29         int d=qn.front();
30         string s=qs.front();
31         if(m.find(s)==m.end())//如果s在map中没有被记录过
32         {
33             m[s]=1;//mark一下
34             for(int c=1;c<=n;++c)//枚举六种变换
35             {
36                 s=qs.front();
37                 while((s.find(a[c]))!=-1)//如果找得到子串a[c]
38                 {
39                     string ss=qs.front();//搞一个辅助的ss
40                     int pos=s.find(a[c]);
41                     ss.replace(pos,a[c].size(),b[c]);//把ss替换一下
42                     if(ss==mb)return d+1;//找到了就return
43                     qs.push(ss);
44                     qn.push(d+1);//push当前的收获
45                     s[pos]='*';//把s的这一位换成无关字符,这样下一次就会自动搜下一位了
46                 }
47             }
48         }
49         qs.pop();qn.pop();
50     }
51     return -1;//搜完了还没搜到则无解
52 }
53 int main()
54 {
55     //freopen("a.in","r",stdin);
56     ios::sync_with_stdio(false);
57     cin.tie(false),cout.tie(false);//cin好伴侣(据说能快过scanf
58     cin>>ma>>mb;
59     while(cin>>a[n]>>b[n])n++;
60     n--;
61     int k=bfs();
62     if(k==-1){cout<<"NO ANSWER!";}
63     else cout<<k;
64     return 0;
65 }


不用map判重也不会TLE 差评

 

不用map:
/*
    qwerta
    P1032 字串变换
    Accepted
    100
    代码 C++,1.14KB
    提交时间 2018-09-26 19:14:03
    耗时/内存
    389ms, 64472KB
*/
//(摔

 

posted @ 2018-09-26 19:44  qwertaya  阅读(253)  评论(0编辑  收藏  举报
MDZX
Changsha
Fulan