【NOIP2002】【codevs 1099】字串变换

来源:互联网 发布:淘宝皇冠号多少钱 编辑:程序博客网 时间:2024/06/08 07:09

1099 字串变换 2002年NOIP全国联赛提高组
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题解
题目描述 Description
已知有两个字串 A,B 及一组字串变换的规则(至多6个规则):
     A1>B1
     A2>B2
  规则的含义为:在 A$中的子串 A1B1、A2B2 …。
    例如:AabcdB=’xyz’
  变换规则为:
    ‘abc’->‘xu’ ‘ud’->‘y’ ‘y’->‘yz’

  则此时,AB,其变换的过程为:
   ‘abcd’->‘xud’->‘xy’->‘xyz’

  共进行了三次变换,使得 AB

输入描述 Input Description
输入格式如下:

   AB
   A1B1 \
   A2B2 |-> 变换规则
   … … /
  所有字符串长度的上限为 20。

输出描述 Output Description
若在 10 步(包含 10步)以内能将 AB ,则输出最少的变换步数;否则输出”NO ANSWER!”

样例输入 Sample Input
abcd xyz
abc xu
ud y
y yz

样例输出 Sample Output
3

数据范围及提示 Data Size & Hint
hehe

并没有写双向搜索之类的东西
感谢强大的STL

compare 比较
replace 替换

就每次暴力看是不是相同 相同就换 顺便记个已经换了多少次
注意判环 所以要>10就退出

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <stack>#include <map>#include <queue>using namespace std;const int MAXN = 205;int cnt = 0,ans = 0;map <string,bool> used;string mm[MAXN][2];//输入们 struct edge{    string s;    int step;};//当前串 变化步数 queue < edge > q;bool dms(string s){    q.push((edge){mm[0][0],0});    while(!q.empty()){        edge u = q.front();q.pop();        if(u.s == mm[0][1]) {ans = u.step;return true;}        int len = u.s.length();        for(int i = 0; i < len; i ++)            for(int j = 1; j <= cnt; j ++){                edge w = u;                if(!u.s.compare(i,mm[j][0].length(),mm[j][0])){                    w.s.replace(i,mm[j][0].length(),mm[j][1]),w.step ++;                    if(used[w.s]) continue;                    if(w.step <= 10) q.push(w);                    used[w.s] = true;                }            }    }    return false;}int main(){    cin >> mm[cnt][0] >> mm[cnt][1],cnt ++;//起点和终点     while(cin >> mm[cnt][0] >> mm[cnt][1])  cnt ++;    if(dms(mm[cnt][0])) printf("%d\n",ans);    else puts("NO ANSWER!");//注意输出!!!!!!!!     return 0;}