Shape Lesson HangDian 1181 - Deep Search, Wide Search, and Collection

Posted by Grayda on Mon, 03 Jun 2019 19:25:07 +0200

Problem Description

Uh...Harry had a little trouble in the Transformations class because he didn't remember all the incantations and casually turned a baseball into a hedgehog like Hermione did, but he found a uniform rule for the Transformations incantation: if the incantation ends with a word that starts with b, then it happens to make object A into object B.
Harry has put all the incantations he knows on a list. He wants you to help him figure out if he can finish his teacher's work, turn a B(ball) into a M(Mouse). You know, if he can't do it himself, he has to ask Hermione for help and be forced to listen to a lot of good learning.

Input
There are multiple groups of test data.Each group has multiple lines, one word per line, including only lowercase letters. The number 0 represents the end of a set of inputs.

Output
If Harry can finish his work, output "Yes." or "No." (Don't ignore the period)

Sample Input

so
soon
river
goes
them
got
moon
begin
big
0

Sample Output
Yes.

I think you all understand the topic. If you type in a word like sfaffac, it means s can become c. If you give a series of words, there are many forms of transformation. The Title asks if these coarse transformations can transform b into m...

It's obvious that this is a search question, but then I think it's also possible to use and collect because it's a bit special and has a continuous correspondence.
Next, I'll tell you all three ways:

1. Guangsou (0ms)

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
#define N 1000
bool vis[N];//Mark whether or not it has passed
char str[N][N];
bool flag;//sign
void bfs(int n)
{
    queue<int> q;     //Define a normal queue
    int a,len,i;
    for(i=0;i<n;i++)  //First put all the beginning of b in the queue
    {
        if(str[i][0]=='b')
        {
            vis[i]=true;  //Marker Walk
            q.push(i);
        }
    }
    while(!q.empty())
    {
        a=q.front();
        q.pop();
        len=strlen(str[a])-1;
        if(str[a][len]=='m')    //If m is found, stop the loop
        {
            flag=true;
            return;
        }
        for(i=0;i<n;i++)
        {
            if(vis[i])//Skips Passed
                continue;
            if(str[i][0]==str[a][len])//Queue if relative to last letter
            {
                vis[i]=true;
                q.push(i);
            }
        }
    }
}
int main()
{
    int i,j,m;
    i=0;
    while(~scanf("%s",&str[i]))
    {
        vis[i]=false;
        i++;
        if(str[i-1][0]=='0')      //Wide search on zero input termination tag
        {
            vis[i]=false;
            flag=false;
            bfs(i);
            if(flag)
                printf("Yes.\n");
            else
                printf("No.\n");
            i=0;
        }
    }
    return 0;
}

2. Deep Search (46ms)

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
#define N 10010
int vis[N];//Make sure you mark whether you have searched deep or Runtime Error(STACK_OVERFLOW)
char str[N][N];
bool flag;
int k;
void dfs(char n)
{
    int i,j,l;
    for(i=0;i<k;i++)
    {
        l=strlen(str[i])-1;
        if(str[i][0]==n&&vis[i]==0)
        {
            if(n=='m')     //Search to m Endpoint Return
            {
                flag=true;
                return ;
            }
            vis[i]=1;//Marker Walk
            dfs(str[i][l]); //Search down
            vis[i]=0;//Eliminate markup
        }
    }
    return ;
}
int main()
{
    int i,j,m;
    k=0;
    while(~scanf("%s",&str[k]))
    {
        memset(vis,0,sizeof(vis));
        vis[k]=false;
        k++;
        if(str[k-1][0]=='0')
        {
            vis[k]=false;
            flag=false;
            dfs('b');       //Start search with b as the head
            if(flag)
                printf("Yes.\n");
            else
                printf("No.\n");
            k=0;
        }
    }
    return 0;
}

3. And Search (15ms)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
#define N 10000
int pre[N];
int find(int x)   //With a common ultimate boss
{
    int r=x;
    while(pre[r]!=r)
        r=pre[r];
    return r;
}
int main()
{
    int n,i,j,a,b,mark1,mark2,l;
    char word[1000];
    while(~scanf("%s",&word))
    {
        if(word[0]=='0')
            continue;
        mark1=mark2=0;
        memset(pre,0,sizeof(pre));
        for(i=1;i<=N;i++)
            pre[i]=i;
        l=strlen(word);/*
        a=word[0]-'a'+1;b=word[l-1]-'a'+1;
        if(word[0]=='b')
            mark1=1;
        if(word[l-1]=='m')
            mark2=1;
        pre[find(a)]=pre[find(b)];For the first set of data processing, in fact, this section can not be, later when doing a search found that it can be simplified*/
        while(~scanf("%s",&word))//After processing, if the final boss pointed to by b and M locations is the same boss, then at least b and m are proved to be connected paths, but only direction problems!!!!
                {
            if(word[0]=='0')
                break;
            l=strlen(word);
            a=word[0]-'a'+1;b=word[l-1]-'a'+1;
            if(word[0]=='b')//Prove direction, if there is a command where the first letter is b and the last letter is m, then there must be a path from b to M.
                mark1=1;
            if(word[l-1]=='m')
                mark2=1;
            pre[find(a)]=pre[find(b)];
        }
        if(pre[2]==pre[13]&&mark1==1&&mark2==1)
            printf("Yes.\n");
        else
            printf("No.\n");
    }
    return 0;
}