已知有两个字串 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!"
输入输出样例
输入样例#1:
abcd xyz abc xu ud y y yz
思路:数据范围其实很小的 直接爆搜就好了#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<queue> #include<map> using namespace std; struct node { string a; int stept; }; queue<node>que; int cnt=0; map<string,bool>vis; string a[8],b[8]; string final; string start; int bfs() { node now,next; now.a=start; now.stept=0; que.push(now); vis[start]=1; while(!que.empty()) { now=que.front(); que.pop(); if(now.stept>10) { return -1; } if(now.a==final) { return now.stept; } string te=now.a; int len=te.length(); for(int i=0;i<cnt;i++) { int l=a[i].length(); for(int j=0;j<len;j++) { if(te.substr(j,l)==a[i])//从第j个位置 找到长度为l的子串 { next.a=te; next.a.replace(j,l,b[i]);//从第j个位置 将 长度为l的子串替换成 b[i]; if(!vis[next.a]) { vis[next.a]=1; next.stept=now.stept+1; que.push(next); } } } } } return -1; } int main() { cin>>start; cin>>final; while(cin>>a[cnt]>>b[++cnt]); int ans=bfs(); if(ans!=-1) { printf("%d",ans); } else { printf("NO ANSWER!"); } }
输出样例#1:
3