南邮 OJ 1620 字符串

字符串

时间限制(普通/Java) :  20000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 53            测试通过 : 15 

比赛描述

已知有两个字串 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$




输入

键盘输人文件名。文件格式如下:
A$ B$
A1$ B1$ \
A2$ B2$  |-> 
变换规则
... ... / 
所有字符串长度的上限为 20


输出

输出至屏幕。格式如下:
若在 10 (包含 10)以内能将 A$ 变换为 B$,则输出最少的变换步数;否则输出"NO ANSWER!"


样例输入

abcd wyz
abc xu
ud y
y yz

样例输出

3

题目来源

NUPT




/* Time Limit Exceed at Test 4
#include<iostream>
#include<string>
using namespace std;

#define MAX_STEP 10
int step,len;
string A,B,a[6],b[6];

void dfs(string A,int cs){
	if(cs>step || cs>MAX_STEP){
		return;
	}
	int i,j,temp;
	string s;
	for(i=0;i<(int)A.length();i++){
		temp = (int)A.size()-i;
		for(j=0;j<len;j++){
			if(temp>=(int)a[j].length()){
				s = A.substr(i,a[j].size());
				if(s==a[j]){
					s = A.substr(0,i)+b[j]+A.substr(i+a[j].size(),A.size()-i-a[j].size());
					if(s==B){
						step = cs;
					}else{
						dfs(s,cs+1);
					}
				}
			}
		}
	}
}

int main(){
//	freopen("test.txt","r",stdin);
	cin>>A>>B;
	step = INT_MAX;
	len = 0;
	while(cin>>a[len]>>b[len]){
		len++;
	}
	dfs(A,1);
	if(step!=INT_MAX){
		printf("%d\n",step);
	}else{
		printf("NO ANSWER!\n");
	}
}
*/




/* 3MS
#include<iostream>
using namespace std;

struct node{
    char s[30];
    int dep;
} list1[5010],list2[5010];

char a[7][30],b[7][30];
int n;

bool check(char *s1,char *s2){
	int len1=strlen(s1),len2=strlen(s2);
	if (len1!=len2)
		return false;
    for (int i=0;i<strlen(s1);i++)
        if (s1[i]!=s2[i])
			return false;
    return true;
}
bool pan1(char *s,int i,int x){
    int len=strlen(a[x]);
	for (int j=i;j<i+len;j++)
        if (s[j]!=a[x][j-i])
			return false;
    return true;
}
bool pan2(char *s,int i,int x){
    int len=strlen(b[x]);
	for (int j=i;j<i+len;j++)
        if (s[j]!=b[x][j-i]) return false;
    return true;
}
void bfs(){
    int head1,tail1,head2,tail2,i,j,k,l;
    head1=tail1=head2=tail2=1;
    while(head1<=tail1 && head2<=tail2){
        if(list1[head1].dep+list2[head2].dep>10){
            printf("NO ANSWER!\n");
            return ;
        }
		int len1=strlen(list1[head1].s);
		for( i=0;i<len1;i++){
			for( j=1;j<=n;j++){
                if(pan1(list1[head1].s,i,j)){
					  tail1++;
					  for(k=0;k<i;k++){
						  list1[tail1].s[k]=list1[head1].s[k];
					  }
					  int len2=strlen(b[j]);
					  for(l=0;l<len2;l++,k++){
						  list1[tail1].s[k]=b[j][l];
					  }
					  len2=strlen(list1[head1].s);
					  for(l=i+strlen(a[j]);l<=len2;l++,k++){
						list1[tail1].s[k]=list1[head1].s[l];
					  }
					  list1[tail1].s[k]='\0';
					  list1[tail1].dep=list1[head1].dep+1;
					  for (k=1;k<=tail2;k++){
						if (check(list1[tail1].s,list2[k].s)){
							printf("%d\n",list1[tail1].dep+list2[k].dep);
							return ;
						}
					  }
                }
			}
		}
		len1=strlen(list2[head2].s);
		for(i=0;i<len1;i++){
			for(j=1;j<=n;j++){
                if(pan2(list2[head2].s,i,j)){
                  tail2++;
				  for(k=0;k<i;k++){
					  list2[tail2].s[k]=list2[head2].s[k];
				  }
				  int len2=strlen(a[j]);
				  for(l=0;l<len2;l++,k++){
					  list2[tail2].s[k]=a[j][l];
				  }
				  len2=strlen(list2[head2].s);
				  for(l=i+strlen(b[j]);l<=len2;l++,k++){
                    list2[tail2].s[k]=list2[head2].s[l];
				  }
                  list2[tail2].s[k]='\0';
                  list2[tail2].dep=list2[head2].dep+1;
				  for (k=1;k<=tail1;k++){
                    if (check(list1[k].s,list2[tail2].s))
                    {
                       printf("%d\n",list1[k].dep+list2[tail2].dep);
                       return ;
                    }
				  }
                }
			}
		}
        head1++; head2++;
    }
    printf("NO ANSWER!\n");
}

int main(){
    scanf("%s%s",list1[1].s,list2[1].s);
    n=1;
    while (scanf("%s%s",a[n],b[n])!=EOF) n++;
    n--;
    list1[1].dep=list2[1].dep=0;
    bfs();
    return 0;
}
*/



/* Wrong Answer at Test 4
#include<iostream>

#define MAX_LEN 30
#define MAX_DEP 10
#define MAX_N 5000

struct queueNode{
	char c[MAX_LEN];
	int dep;
}que[MAX_N];
int qHead,qTail;

char a[6][MAX_LEN];
char b[6][MAX_LEN];
char target[MAX_LEN];
int aSize;

//c2字符串等于c1前面同等长度的字符串
bool hasSub(char *c1,char *c2){
	while(*c2 && *c1==*c2){
		c1++;
		c2++;
	}
	if(*c2){
		return 0;
	}
	return 1;
}

int main(){
//	freopen("test.txt","r",stdin);
	char *p,*q;
	int depth,len1,len2,i,j,k,l;
	scanf("%s%s",que[qTail++].c,target);
	if(strcmp(que[qHead].c,target)==0){
		printf("0\n");
		return 0;
	}
	while(scanf("%s%s",a[aSize],b[aSize])==2){
		aSize++;
	}
	while(qHead<=qTail){
		depth = que[qHead].dep+1;
		if(depth>MAX_DEP){
			break;
		}
		p = que[qHead++].c;
		len1 = (int)strlen(p);
		for(i=0;i<len1;i++){
			for(j=0;j<aSize;j++){
				if(hasSub(p+i,a[j])){
					q = que[qTail].c;
					que[qTail++].dep = depth;
					for(k=0;k<i;k++){
						q[k] = p[k];			//原字符串前面的部分
					}
					len2 = (int)strlen(b[j]);
					for(l=0;l<len2;l++,k++){	//被替换掉的部分
						q[k] = b[j][l];
					}
					len2 = (int)strlen(p);
					for(l=i+(int)strlen(a[j]);l<len2;l++,k++){
						q[k] = p[l];
					}
					q[k] = 0;
					if(strcmp(q,target)==0){
						printf("%d\n",depth);
						return 0;
					}
				}
			}
		}
	}
	printf("NO ANSWER!\n");
}
*/


/*
// Runtime Error at Test 5 
//(ACCESS_VIOLATION)
//由于数据范围的原因,单项搜索就不行,必须要双向搜索
#include<iostream>
using namespace std;

struct node{
    char s[300];
    int dep;
} list1[50100];

char a[7][30],b[7][30],target[30];
int n;
bool pan1(char *s,int i,int x){
    int len=strlen(a[x]);
	for (int j=i;j<i+len;j++)
        if (s[j]!=a[x][j-i])
			return false;
    return true;
}
void bfs(){
    int head1,tail1,i,j,k,l;
    head1=tail1=1;
    while(head1<=tail1){
        if(list1[head1].dep>10){
            printf("NO ANSWER!\n");
            return ;
        }
		int len1=strlen(list1[head1].s);
		for( i=0;i<len1;i++){
			for( j=1;j<=n;j++){
                if(pan1(list1[head1].s,i,j)){
				tail1++;
				for(k=0;k<i;k++){
				  list1[tail1].s[k]=list1[head1].s[k];
				}
				int len2=strlen(b[j]);
				for(l=0;l<len2;l++,k++){
				  list1[tail1].s[k]=b[j][l];
				}
				len2=strlen(list1[head1].s);
				for(l=i+strlen(a[j]);l<=len2;l++,k++){
				list1[tail1].s[k]=list1[head1].s[l];
				}
				list1[tail1].s[k]='\0';
				list1[tail1].dep=list1[head1].dep+1;
					if (strcmp(list1[tail1].s,target)==0){
						printf("%d\n",list1[tail1].dep);
						return ;
					}
                }
			}
		}
        head1++;
    }
    printf("NO ANSWER!\n");
}

int main(){
//	freopen("test.txt","r",stdin);
    scanf("%s%s",list1[1].s,target);
    n=1;
    while (scanf("%s%s",a[n],b[n])!=EOF) n++;
    n--;
    list1[1].dep=0;
    bfs();
    return 0;
}
*/





/* WA4
#include<iostream>

#define MAX_LEN 30
#define MAX_DEP 10
#define MAX_N 5000

struct queueNode{
	char c[MAX_LEN];
	int dep;
}que1[MAX_N],que2[MAX_N];
int head1,tail1,head2,tail2;

char a[6][MAX_LEN];
char b[6][MAX_LEN];
int aSize;

//c2字符串等于c1前面同等长度的字符串
bool hasSub(char *c1,char *c2){
	while(*c2 && *c1==*c2){
		c1++;
		c2++;
	}
	if(*c2){
		return 0;
	}
	return 1;
}

int main(){
	freopen("test.txt","r",stdin);
	char *p,*q;
	int depth1,depth2,len1,len2,i,j,k,l;
	scanf("%s%s",que1[tail1++].c,que2[tail2++].c);
	if(strcmp(que1[head1].c,que2[head2].c)==0){
		printf("0\n");
		return 0;
	}
	while(scanf("%s%s",a[aSize],b[aSize])==2){
		aSize++;
	}
	while(head1<=tail1 && head2<=tail2){
		depth1 = que1[head1].dep+1;
		depth2 = que2[head2].dep+1;
		if(depth1+depth2 > MAX_DEP){
			break;
		}
		if(tail1-head1 <= tail2-head2){
			p = que1[head1++].c;
			len1 = (int)strlen(p);
			for(i=0;i<len1;i++){
				for(j=0;j<aSize;j++){
					if(hasSub(p+i,a[j])){
						q = que1[tail1].c;
						que1[tail1++].dep = depth1;
						for(k=0;k<i;k++){
							q[k] = p[k];			//原字符串前面的部分
						}
						len2 = (int)strlen(b[j]);
						for(l=0;l<len2;l++,k++){	//被替换掉的部分
							q[k] = b[j][l];
						}
						len2 = (int)strlen(p);
						for(l=i+(int)strlen(a[j]);l<len2;l++,k++){
							q[k] = p[l];
						}
						q[k] = 0;
						for(k=head2;k<tail2;k++){
							if(strcmp(q,que2[k].c)==0){
								printf("%d\n",depth1+que2[k].dep);
								return 0;
							}
						}
					}
				}
			}
		}
		if(tail2-head2 <= tail1-head1){
			p = que2[head2++].c;
			len1 = (int)strlen(p);
			for(i=0;i<len1;i++){
				for(j=0;j<aSize;j++){
					if(hasSub(p+i,b[j])){
						q = que2[tail2].c;
						que2[tail2++].dep = depth2;
						for(k=0;k<i;k++){
							q[k] = p[k];			//原字符串前面的部分
						}
						len2 = (int)strlen(a[j]);
						for(l=0;l<len2;l++,k++){	//被替换掉的部分
							q[k] = a[j][l];
						}
						len2 = (int)strlen(p);
						for(l=i+(int)strlen(b[j]);l<len2;l++,k++){
							q[k] = p[l];
						}
						q[k] = 0;
						for(k=head1;k<tail1;k++){
							if(strcmp(q,que1[k].c)==0){
								printf("%d\n",depth2+que1[k].dep);
								return 0;
							}
						}
					}
				}
			}
		}
	}
	printf("NO ANSWER!\n");
}
*/




/* AC 0MS
#include<iostream>
using namespace std;

struct node{
    char s[30];
    int dep;
} list1[5010],list2[5010];

char a[7][30],b[7][30];
int n;

bool check(char *s1,char *s2){
	while(*s1 && *s2 && *s1==*s2){
		s1++;
		s2++;
	}
	if(*s1==0 && *s2==0){
		return 1;
	}
	return 0;
}
bool pan1(char *s,int i,int x){
    int len=strlen(a[x]);
	for (int j=i;j<i+len;j++)
        if (s[j]!=a[x][j-i])
			return false;
    return true;
}
bool pan2(char *s,int i,int x){
    int len=strlen(b[x]);
	for (int j=i;j<i+len;j++)
        if (s[j]!=b[x][j-i]) return false;
    return true;
}
void bfs(){
    int head1,tail1,head2,tail2,i,j,k,l;
    head1=tail1=head2=tail2=1;
    while(head1<=tail1 && head2<=tail2){
        if(list1[head1].dep+list2[head2].dep>10){
            printf("NO ANSWER!\n");
            return ;
        }
		int len1=strlen(list1[head1].s);
		for( i=0;i<len1;i++){
			for( j=1;j<=n;j++){
                if(pan1(list1[head1].s,i,j)){
					  tail1++;
					  for(k=0;k<i;k++){
						  list1[tail1].s[k]=list1[head1].s[k];
					  }
					  int len2=strlen(b[j]);
					  for(l=0;l<len2;l++,k++){
						  list1[tail1].s[k]=b[j][l];
					  }
					  len2=strlen(list1[head1].s);
					  for(l=i+strlen(a[j]);l<=len2;l++,k++){
						list1[tail1].s[k]=list1[head1].s[l];
					  }
					  list1[tail1].s[k]='\0';
					  list1[tail1].dep=list1[head1].dep+1;
					  for (k=1;k<=tail2;k++){
						if (check(list1[tail1].s,list2[k].s)){
							printf("%d\n",list1[tail1].dep+list2[k].dep);
							return ;
						}
					  }
                }
			}
		}
		len1=strlen(list2[head2].s);
		for(i=0;i<len1;i++){
			for(j=1;j<=n;j++){
                if(pan2(list2[head2].s,i,j)){
                  tail2++;
				  for(k=0;k<i;k++){
					  list2[tail2].s[k]=list2[head2].s[k];
				  }
				  int len2=strlen(a[j]);
				  for(l=0;l<len2;l++,k++){
					  list2[tail2].s[k]=a[j][l];
				  }
				  len2=strlen(list2[head2].s);
				  for(l=i+strlen(b[j]);l<=len2;l++,k++){
                    list2[tail2].s[k]=list2[head2].s[l];
				  }
                  list2[tail2].s[k]='\0';
                  list2[tail2].dep=list2[head2].dep+1;
				  for (k=1;k<=tail1;k++){
                    if (check(list1[k].s,list2[tail2].s))
                    {
                       printf("%d\n",list1[k].dep+list2[tail2].dep);
                       return ;
                    }
				  }
                }
			}
		}
        head1++; head2++;
    }
    printf("NO ANSWER!\n");
}

int main(){
    scanf("%s%s",list1[1].s,list2[1].s);
    n=1;
    while (scanf("%s%s",a[n],b[n])!=EOF) n++;
    n--;
    list1[1].dep=list2[1].dep=0;
    bfs();
    return 0;
}
*/



// AC 0MS
#include<iostream>
using namespace std;

struct node{
    char s[30];
    int dep;
} list1[5010],list2[5010];

char a[7][30],b[7][30];
int n;
//判断s1、s2字符串是否相等
bool equal(char *s1,char *s2){
	while(*s1 && *s2 && *s1==*s2){
		s1++;
		s2++;
	}
	if(*s1==0 && *s2==0){
		return 1;
	}
	return 0;
}
//判断s2是否为s1的前缀
bool preEqual(char *c1,char *c2){
	while(*c2 && *c1==*c2){
		c1++;
		c2++;
	}
	if(*c2){
		return 0;
	}
	return 1;
}

void bfs(){
    int head1,tail1,head2,tail2,i,j,k,l;
    head1=tail1=head2=tail2=1;
    while(head1<=tail1 && head2<=tail2){
        if(list1[head1].dep+list2[head2].dep>10){
            printf("NO ANSWER!\n");
            return ;
        }
		int len1=strlen(list1[head1].s);
		for( i=0;i<len1;i++){
			for( j=1;j<=n;j++){
				if(preEqual(list1[head1].s+i,a[j])){
					tail1++;
					for(k=0;k<i;k++){
					  list1[tail1].s[k]=list1[head1].s[k];
					}
					int len2=strlen(b[j]);
					for(l=0;l<len2;l++,k++){
					  list1[tail1].s[k]=b[j][l];
					}
					len2=strlen(list1[head1].s);
					for(l=i+strlen(a[j]);l<=len2;l++,k++){
					list1[tail1].s[k]=list1[head1].s[l];
					}
					list1[tail1].s[k]=0;
					list1[tail1].dep=list1[head1].dep+1;
					for (k=1;k<=tail2;k++){
						if (equal(list1[tail1].s,list2[k].s)){
							printf("%d\n",list1[tail1].dep+list2[k].dep);
							return ;
						}
					}
                }
			}
		}
		len1=strlen(list2[head2].s);
		for(i=0;i<len1;i++){
			for(j=1;j<=n;j++){
				if(preEqual(list2[head2].s+i,b[j])){
					tail2++;
					for(k=0;k<i;k++){
						list2[tail2].s[k]=list2[head2].s[k];
					}
					int len2=strlen(a[j]);
					for(l=0;l<len2;l++,k++){
						list2[tail2].s[k]=a[j][l];
					}
					len2=strlen(list2[head2].s);
					for(l=i+strlen(b[j]);l<=len2;l++,k++){
						list2[tail2].s[k]=list2[head2].s[l];
					}
					list2[tail2].s[k]=0;
					list2[tail2].dep=list2[head2].dep+1;
					for (k=1;k<=tail1;k++){
						if (equal(list1[k].s,list2[tail2].s)){
							printf("%d\n",list1[k].dep+list2[tail2].dep);
							return ;
						}
					}
                }
			}
		}
        head1++;
		head2++;
    }
    printf("NO ANSWER!\n");
}

int main(){
//	freopen("test.txt","r",stdin);
	scanf("%s%s",list1[1].s,list2[1].s);
	n=1;
	while (scanf("%s%s",a[n],b[n])!=EOF){
		n++;
	}
	n--;
	list1[1].dep=list2[1].dep=0;
	bfs();
	return 0;
}



你可能感兴趣的:(字符串,ACM,南邮OJ)