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
题解
这种字符串变换都是考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 */ //(摔