大暴搜 字串变换

  

65. [NOIP2002] 字串变换

时间限制:1 s   内存限制:128 MB

[问题描述]

已知有两个字串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 xyz
abc xu
ud y
y yz

[输出样例]

3 
正解就是搜,深搜会超时,可以考虑广搜,即双向广搜,可以防止被卡数据,比如正向搜过慢,而反向搜很快的点。
先贴一发我dfs+神剪枝+卡数据的搜
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
string A,B,a[10],b[10];
int n=1,ans=11,cnt=0;
map<string,int> mp;
void dfs(string x,int len)
{
    cnt++;
    if(cnt>=40000){printf("NO ANSWER!
");exit(0);}//深搜次数过多直接输出无解,卡数据。
	if(len>10||x.size()>20||len>ans)return;
	if(x==B){
	    ans=min(ans,len);
	    return;
	}
	string f=x;int k;
	for(int i=1;i<=n;i++){
		for(int j=0;j<x.size();j++)
		{
		   k=x.find(a[i],j);
	       if(k<100&&k>=0)
	       {
		  	    int l=a[i].size();
				x.replace(k,l,b[i]);
		  	    if(!mp.count(x))mp[x]=len,dfs(x,len+1);
		  	    else if(len<mp[x])dfs(x,len+1);
		  	    x=f;
		   }
		}
	}
}
int yjn()
{
	freopen("string.in","r",stdin);
	freopen("string.out","w",stdout);
	cin>>A>>B;
	while(cin>>a[n])cin>>b[n++];
	n--;
	mp[A]=++cnt;
	dfs(A,0);
	if(ans==11)printf("NO ANSWER!
");
	else cout<<ans;
}
int qty=yjn();
int main(){;}

再贴一发正解
 
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<map>
  6. #include<string>
  7. #include<queue>
  8. using namespace std;
  9. struct node
  10. {
  11. string s;int num;
  12. };
  13. queue<node>q1,q2;
  14. map<string,int>m1,m2;
  15. string changings[6][2];
  16. int cnt,ans;
  17. string become(string now,int pos,int n,string tmp)
  18. {
  19. return now.replace(pos,n,tmp);
  20. }
  21. bool dbfs()
  22. {
  23. while(!q1.empty()&&!q2.empty())
  24. {
  25. node s1=q1.front(),s2;q1.pop();
  26. int len=s1.s.size();
  27. for(int i=0;i<len;i++)
  28. for(int j=0;j<cnt;j++)
  29. {
  30. int siz=changings[j][0].size();
  31. if(i+siz-1<len&&!s1.s.compare(i,siz,changings[j][0])&&!m1.count(become(s1.s,i,siz,changings[j][1])))
  32. {
  33. s2.s=become(s1.s,i,siz,changings[j][1]);
  34. s2.num=s1.num+1;
  35. if(s2.num>10)return 0;
  36. m1[s2.s]=s2.num;q1.push(s2);
  37. if(m2.count(s2.s))
  38. {
  39. ans=s2.num+m2[s2.s];
  40. return 1;
  41. }
  42. }
  43. }
  44. s1=q2.front(),s2;q2.pop();
  45. len=s1.s.size();
  46. for(int i=0;i<len;i++)
  47. for(int j=0;j<cnt;j++)
  48. {
  49. int siz=changings[j][1].size();
  50. if(i+siz-1<len&&!s1.s.compare(i,siz,changings[j][1])&&!m2.count(become(s1.s,i,siz,changings[j][0])))
  51. {
  52. s2.s=become(s1.s,i,siz,changings[j][0]);
  53. s2.num=s1.num+1;
  54. if(s2.num>10)return 0;
  55. m2[s2.s]=s2.num;q2.push(s2);
  56. if(m1.count(s2.s))
  57. {
  58. ans=s2.num+m1[s2.s];
  59. return 1;
  60. }
  61. }
  62. }
  63. }
  64. return 0;
  65. }
  66. int haha()
  67. {
  68. freopen("string.in","r",stdin);
  69. freopen("string.out","w",stdout);
  70. node a,b;cin>>a.s>>b.s;
  71. if(a.s==b.s)
  72. {
  73. cout<<0;
  74. return 0;
  75. }
  76. a.num=b.num=0;
  77. q1.push(a);q2.push(b);
  78. while(cin>>changings[cnt][0]>>changings[cnt][1])cnt++;
  79. m1[a.s]=0;m2[b.s]=0;
  80. if(dbfs())cout<<ans;
  81. else puts("NO ANSWER!");
  82. }
  83. int sb=haha();
  84. int main(){;}
原文地址:https://www.cnblogs.com/QTY2001/p/7632729.html