【NOIP2002】【codevs 1099】字串变换

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;
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Loi_Shirley/article/details/78288014
个人分类: ===STL===
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭