【lightoj-1039】A Toy Company(BFS)

The toy company "Babies Toys" has hired you to help develop educational toys. The current project is a word toy that displays three letters at all times. Below each letter are two buttons that cause the letter above to change to the previous or next letter in alphabetical order. So, with one click of a button the letter 'c' can be changed to a 'b' or a 'd'. The alphabet is circular, so for example an 'a' can become a 'z' or a 'b' with one click.

In order to test the toy, you would like to know if a word can be reached from some starting word, given one or more constraints. A constraint defines a set of forbidden words that can never be displayed by the toy. Each constraint is formatted like "X X X", where each X is a string of lowercase letters. A word is defined by a constraint if the ith letter of the word is contained in the ith X of the constraint. For example, the constraint "lf a tc" defines the words "lat", "fat", "lac" and "fac".

You will be given a string start, a string finish, and some forbidden strings. Calculate and return the minimum number of button presses required for the toy to show the word finish if the toy was originally showing the word start. Remember, the toy must never show a forbidden word. If it is impossible for the toy to ever show the desired word, return -1.

Input

Input starts with an integer T (≤ 50), denoting the number of test cases.

Each case begins with a blank line and two strings in two lines, start and finish both having exactly three characters each. The next line contains an integer n (1 ≤ n ≤ 50) denoting the number of forbidden words. Each of the next n lines will contain three strings each, separated by a single space. Each string (all the three strings) in a line will contain only distinct letters. Remember that start or finish can be forbidden. You can assume that all the characters are lowercase.

Output

For each case of input you have to print the case number and desired result.

Sample Input

Output for Sample Input

3

aab

zna

8

a a a

a a z

a z a

z a a

a z z

z a z

z z a

z z z

aaa

aaa

0

aab

nnn

1

a a ab

Case 1: 15

Case 2: 0

Case 3: -1

 【题意】

给两个字符串和几个限制,求出第一个变成第二个字符串所需要的最小步数,不能输出-1.

【代码】

#include <bits/stdc++.h>
using namespace std;
char s[4], e[4], s1[100], s2[100], s3[100];
bool vis[30][30][30], flag;
struct node
{
    int a, b, c, step;
};
node S, E;
int bfs()
{
    if(flag) return -1;
    queue<node>Q;
    S.step = 0;
    Q.push(S);
    vis[S.a][S.b][S.c] = true;
    int m;
    while(!Q.empty())
    {
        node t = Q.front();
        Q.pop();
        if(t.a == E.a && t.b == E.b && t.c == E.c) return t.step;
        m = (t.a+1)%26;
        if(!vis[m][t.b][t.c])
        {
            node tt;
            tt.a = m, tt.b = t.b, tt.c = t.c;
            tt.step = t.step+1;
            vis[m][t.b][t.c] = 1;
            Q.push(tt);
        }
        m = (t.a+26-1)%26;
        if(!vis[m][t.b][t.c])
        {
            node tt;
            tt.a = m, tt.b = t.b, tt.c = t.c;
            tt.step = t.step+1;
            vis[m][t.b][t.c] = 1;
            Q.push(tt);
        }
        m = (t.b+1)%26;
        if(!vis[t.a][m][t.c])
        {
            node tt;
            tt.a = t.a, tt.b = m, tt.c = t.c;
            tt.step = t.step+1;
            vis[t.a][m][t.c] = 1;
            Q.push(tt);
        }
        m = (t.b+26-1)%26;
        if(!vis[t.a][m][t.c])
        {
            node tt;
            tt.a = t.a, tt.b = m, tt.c = t.c;
            tt.step = t.step+1;
            vis[t.a][m][t.c] = 1;
            Q.push(tt);
        }
        m = (t.c+1)%26;
        if(!vis[t.a][t.b][m])
        {
            node tt;
            tt.a = t.a, tt.b = t.b, tt.c = m;
            tt.step = t.step+1;
            vis[t.a][t.b][m] = 1;
            Q.push(tt);
        }
        m = (t.c+26-1)%26;
        if(!vis[t.a][t.b][m])
        {
            node tt;
            tt.a = t.a, tt.b = t.b, tt.c = m;
            tt.step = t.step+1;
            vis[t.a][t.b][m] = 1;
            Q.push(tt);
        }
    }
    return -1;
}
int main()
{
    int t, n;
    cin>>t;
    int cas = 0;
    while(t--)
    {
        memset(vis, 0, sizeof vis);
        scanf("%s%s%d", s, e, &n);
        S.a = s[0]-'a', S.b = s[1]-'a', S.c = s[2]-'a';
        E.a = e[0]-'a', E.b = e[1]-'a', E.c = e[2]-'a';
        for(int i = 1; i <= n; i++)
        {
            scanf("%s%s%s", s1, s2, s3);
            int l1 = strlen(s1);
            int l2 = strlen(s2);
            int l3 = strlen(s3);
            for(int j = 0; j < l1; j++)
                for(int k = 0; k < l2; k++)
                    for(int l = 0; l < l3; l++)
                        vis[s1[j]-'a'][s2[k]-'a'][s3[l]-'a'] = true;
        }
        flag = false;
        if(vis[S.a][S.b][S.c] || vis[E.a][E.b][E.c]) flag = true;
        printf("Case %d: %d
", ++cas, bfs());
    }
    return 0;
}
原文地址:https://www.cnblogs.com/lesroad/p/8619122.html