本文主要是介绍洛谷 P1032 字串变换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目描述
已知有两个字串 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。
共进行了 3 次变换,使得 A 变换为 B。
输入格式
第一行有两个字符串 A,B。
接下来若干行,每行有两个字符串 Ai,Bi,表示一条变换规则。
输出格式
若在 10 步(包含 10 步)以内能将 A 变换为 B,则输出最少的变换步数;否则输出 NO ANSWER!
。
输入输出样例
输入 #1
abcd xyz abc xu ud y y yz
输出 #1
3
说明/提示
对于 100% 数据,保证所有字符串长度的上限为 20。
【题目来源】
NOIP 2002 提高组第二题
解题思路
采用广度搜索,字符串匹配采用朴素模式匹配也可以,需要注意的是,主串可能有多个子串匹配成功,在bfs中都需要加入列队(别看只有6个规则,列队数组却比较大,不然RE等你)
AC代码
#include<stdio.h>
#include<string.h>
struct nb {//储存变化规则char s[23];//变化前char h[23];//变化后
}e[8];
struct linknode {//列队char g[23];//串int s;//步数
}link[2110000];
int main()
{int k = 1;char a[23], b[23];scanf("%s %s", a, b); //输入起始串和终止串while (scanf("%s %s", e[k].s, e[k].h)!=EOF)//输入规则k++;int hard = 1, tail = 2, flag = 0;strcpy(link[1].g, a); link[1].s = 0;//起始串入队while (hard < tail && link[hard].s < 10){for (int i = 1; i < k; i++)//列举所有变化规则{int x = 0, y = 0;int p = strlen(link[hard].g);int q = strlen(e[i].s);while (x < p)//继续寻找主串后面是否有匹配的{while (x < p && y < q)//朴素模式匹配{if (link[hard].g[x] == e[i].s[y]){x++; y++;}else{x = x - y + 1;y = 0;}}if (y == q)//y==q代表匹配成功{int mm = 0;//入队操作for (int j = 0; j < x - y; j++)link[tail].g[mm++] = link[hard].g[j];int hj = strlen(e[i].h);for (int j = 0; j < hj; j++)link[tail].g[mm++] = e[i].h[j];for (int j = x; j < p; j++)link[tail].g[mm++] = link[hard].g[j];link[tail].g[mm] = '\0'; link[tail].s = link[hard].s + 1;if (strcmp(link[tail].g, b) == 0)//如果找到终点串结束{flag = 1;break;}tail++;}y = 0;}if (flag == 1)break;}if (flag == 1)break;hard++;//一个点广搜结束进行下一个}if (flag == 1)//找到终点串{if (link[tail].s <= 10)printf("%d", link[tail].s);elseprintf("NO ANSWER!");}else//没找到终点串printf("NO ANSWER!");return 0;
}
这篇关于洛谷 P1032 字串变换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!