广搜——变换类

Wikioi 1099 字串变换

题目描述 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

思路:

双向广搜

代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 struct node
 4 {
 5     char s[30];
 6     int dep;  //变换次数
 7 } list1[5010], list2[5010];
 8 char a[7][30], b[7][30];
 9 int n;
10 void BFS()
11 {
12     int head1, tail1, head2, tail2, k;
13     head1 = tail1 = head2 = tail2 = 1;
14     while(head1 <= tail1 && head2 <= tail2)
15     {
16         if(list1[head1].dep + list2[head2].dep > 10)
17         {
18             printf("NO ANSWER!\n");
19             return ;
20         }
21         for(int i = 0;i < strlen(list1[head1].s); i++)
22             for(int j = 1; j <= n; j++)
23                 if(strncmp(list1[head1].s + i, a[j], strlen(a[j])) == 0) //寻找当前可变换的规则
24                 {
25                   tail1++; //移动尾指针,存储变换后的字符串,以下三个for循环为变换过程
26                   for(k = 0; k < i; k++)
27                       list1[tail1].s[k] = list1[head1].s[k];
28                   for(int l = 0; l < strlen(b[j]); l++, k++)
29                       list1[tail1].s[k] = b[j][l];
30                   for(int l = i + strlen(a[j]); l <= strlen(list1[head1].s); l++, k++)
31                      list1[tail1].s[k] = list1[head1].s[l];
32                   list1[tail1].s[k] = ‘\0‘; //为变换结束后的字符串加结束符
33                   list1[tail1].dep = list1[head1].dep+1;
34                   for (k = 1; k <= tail1; k++)
35                     if (strcmp(list1[tail1].s, list2[k].s) == 0)//判断当前状态是否与逆向搜索交汇
36                     {
37                        printf("%d\n", list1[tail1].dep + list2[k].dep);
38                        return ;
39                      }
40                 }
41         for (int i = 0; i < strlen(list2[head2].s); i++) //逆向搜索同上
42             for (int j = 1; j <= n; j++)
43                 if(strncmp(list2[head2].s + i, b[j], strlen(b[j])) == 0)
44                 {
45                   tail2++;
46                   for(k = 0; k < i; k++)
47                       list2[tail2].s[k] = list2[head2].s[k];
48                   for(int l = 0; l < strlen(a[j]); l++, k++)
49                       list2[tail2].s[k] = a[j][l];
50                   for(int l = i + strlen(b[j]); l <= strlen(list2[head2].s); l++, k++)
51                     list2[tail2].s[k] = list2[head2].s[l];
52                   list2[tail2].s[k] = ‘\0‘;
53                   list2[tail2].dep = list2[head2].dep + 1;
54                   for (k = 1;k <= tail1; k++)
55                     if (strcmp(list1[k].s, list2[tail2].s) == 0)
56                     {
57                        printf("%d\n",list1[k].dep + list2[tail2].dep);
58                        return ;
59                     }
60                 }
61         head1++;
62         head2++;
63     }
64     printf("NO ANSWER!\n");
65 }
66 int main()
67 {
68     scanf("%s%s",list1[1].s, list2[1].s);
69     n = 1;
70     while (scanf("%s%s",a[n],b[n]) != EOF)
71         n++;
72 n--;
73     list1[1].dep = list2[1].dep = 0;
74     BFS();
75     return 0;
76 } 

时间: 2024-12-24 23:55:47

广搜——变换类的相关文章

洛谷 P1032 字串变换 广搜

这道题原本我用深搜,结果会T,wcnm,然后就直接参考抄题解了 1 Const maxn=10000; 2 maxq=100000; 3 Var a:array[0..1,0..maxn]of string;//变换规则 4 q:array[0..1,0..maxq]of string;//两个队列 5 step:array[0..1,0..maxn]of longint;//步数 6 head,tail:array[0..1]of longint;//两个队列的头指针和尾指针 7 int,ai

NYOJ 284 坦克大战 &amp;&amp; POJ 2312 Battle City (广搜+优先队列)

链接:click here~~ 题意: 描述 Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it on computer now. What we are discussing is a simple edition of this game. Given a map that consists of empty space

宽搜和广搜、

广搜与深搜的小区别 一般来说,广搜常用于找单一的最短路线,或者是规模小的路径搜索,它的特点是"搜到就是最优解", 而深搜用于找多个解或者是"步数已知(好比3步就必需达到前提)"的标题,它的空间效率高,然则找到的不必定是最优解,必需记实并完成全数搜索,故一般情况下,深搜需要很是高效的剪枝(优化). 像搜索最短路径这些的很显著若是用广搜,因为广搜的特征就是一层一层往下搜的,保证当前搜到的都是最优解,当然,最短路径只是一方面的操作,像什么起码状态转换也是可以操作的.深搜就

双向广搜 POJ 3126 Prime Path

POJ 3126  Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16204   Accepted: 9153 Description The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change th

poj 3984:迷宫问题(广搜,入门题)

迷宫问题 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7635   Accepted: 4474 Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要

POJ 3126 Prime Path( 广搜 )

Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12974   Accepted: 7342 Description The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-dig

HDU 1195 Open the Lock (双向广搜)

题意:给你初始4个数字和目标4个数字,问是否能由初始经过变换到目标数字: 变换规则:每个数字可以加1(9+1=1)或减1(1-1=9),或交换相邻的数字(最左和最右不是相邻的). 双向广搜:分别对初始和目标数字进行广搜,vis数组用1和2标记两种已搜索的数字,用mp数组记录状态的步数. 当从前往后搜可以到达2或从后往前搜可以到达1状态则就可以了... #include<stdio.h> #include<string.h> #include<string> #inclu

leetcode Word Ladder 广搜

利用两个队列(或vector):curlevel和nextlvevl分别表示当前层的所有可能状态和转换到的下一层的所有可能状态.我们的目标是转换到end单词即可,深搜会超时.使用广搜,各层的可能结点同时向下进行,找到end即可return.当找完当前层的所有可能结点后,当前层也就空了,然后swap(当前层,下一层)循环向下搜索. 下面两个代码都是用这个方法,第一个超时,使用第二段代码,对于每个结点,只需找25*len种下一个可能结点是否存在,第一段代码需要在大数据里慢慢找. note:在一个字符

双向广搜+hash+康托展开 codevs 1225 八数码难题

codevs 1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找