UVA - 310 - L--system

题意:在D0L这样一个系统中存在一个有限的集合(包含字母),一个P集合(字母的映射)和一个初始串。题目给定一个初始串,叫你判断是否能通过不断映射构成目标串或者包含该目标串的串。例如a->aa,b->bb,初始串为ab,目标串为aaabb,这样的话,初始串根据映射衍化(注意,扩展时必须同时采用两规则):ab(a->aa,b->bb)->aabb->aaaabbbb 这样就得到了含有目标串的串,输出YES。
思路:
        1.BFS穷举所有状态。
        2.保存每个状态。
        3.存储所有和目标串长度相等的状态,利用HASH判重。
eg:
aa
bb
ab
aaaaabb
aaaaaaaaaabbbbb
aaaaaabbbbbbbbb
baaaababababaaa
abababbb
a
b
ab
ba
a
b
ab
ab
a
b
aaab
ba
YES
NO
NO
YES
NO
#include<stdio.h>
#include<string.h>
#define MAXSIZE 1000003
char aRight[20],bRight[20],start[20],dest[20];
char state[MAXSIZE][20];
int len,flag;
int hash[MAXSIZE],aimValue; 
int getValue(int n)
{
    int i,v=0;
    for(i=0;i<strlen(state[n]);i++)
    {
        v=v*2+state[n][i]-'a'+1;
    } 
    return v;
}    
          
void BFS()
{
    int front=0,rear=0,i,j,k,tag=0;
    char current[20],temp[200];
    memset(current,0,sizeof(current));
    memset(temp,0,sizeof(temp));
    memset(hash,0,sizeof(hash));
    aimValue=0;
    for(i=0;i<strlen(dest);i++)
    {
        aimValue=aimValue*2+dest[i]-'a'+1;
    }    
    if(strstr(start,dest)!=NULL)
    {
        flag=1;
        return;
    }    
    //穷举存入初始状态  
    for(i=0;i<strlen(start);i++)
    {
        tag=0;
        for(j=i,k=0;j<strlen(start)&&k<len;j++,k++)
        {
            state[rear][k]=start[j];
        }
        state[rear][k]='\0';
        tag=getValue(rear);
        if(!hash[tag])
        {
            hash[tag]=1;
            rear++;
        }
    }                                 
    while(front<rear)
    {
        if(hash[aimValue]){flag=1;return;} 
        strcpy(current,state[front]);
        memset(temp,0,sizeof(temp)); 
        //穷举扩展
        for(i=0;i<strlen(current);i++)
        {
            if(current[i]=='a')
            {
                strcat(temp,aRight);
            }
            else if(current[i]=='b')
            {
                strcat(temp,bRight);
            }
        }    
        //hash判重,存储   
        for(i=0;i<strlen(temp);i++)
        {
            for(j=i,k=0;j<strlen(temp)&&k<len;j++,k++)
            {
                state[rear][k]=temp[j];
            }
            state[rear][k]='\0';    
            tag=getValue(rear);
            if(!hash[tag])
            {
                hash[tag]=1;
                rear++;
            }          
        }    
        front++;
    }    
}    
int main()
{
    while(scanf("%s",aRight)!=EOF)
    {
        scanf("%s%s%s",bRight,start,dest);
        flag=0;
        len=strlen(dest);
        BFS();
        if(flag||dest[0]=='\0')printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}        
    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值