1016 [NOIP2002]字串变换 双向广搜
题目描述
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 B1A_1\ B_1A1 B1 \
A2 B2A_2\ B_2A2 B2 |-> 变换规则
... ... /
所有字符串长度的上限为 20。
输出描述:
输出格式如下:
若在10步(包含 10步)以内能将A变换为B,则输出最少的变换步数;否则输出"NO ANSWER!"
示例1
abcd xyz
abc xu
ud y
y yz
3
解答
1.读完题目,样例模拟成功,但感觉该题挺难的,无从下手。2.看了雨巨的写法,才知道可以bfs,因为条件很少,所以直接pos = string.find(a[i]);tmp.erase(pos,a[i].size());tmp.insert(pos,b[i]);就可以实现字串查找和替换
3.然后想到同一个字串有多个位置可以替换 就可以改pos = string.find(a[i],j) 用j来循环原串中的位置
4.然后就是各种剪枝,最后发现还是不行,只能双向广搜。
5.最后看了别人的代码,改了很多细节。。。交上去始终a不了,才发现搜的时候忘记传ed了。。。。好菜
6.过程中发现别人代码有几个bug,比如应该是<cnt 还有q.push(mp[tmp]) 才对;
7.
//-------------------------代码----------------------------
//#define int LL
const int N = 1e6+10;
string st,ed;
map<string,int>mp;
string vis[N];
int cnt = 1;
string a[N],b[N];
int distA[N],distB[N];
int n = 0;
int bfs(string st,int dist[],string a[],string b[]) {
queue<int> q;
mp[st]= n;
vis[n]=st;
q.push(n);
dist[n]=0;
n ++ ;
while(q.size()) {
int t=q.front();q.pop();
// cout<<ys[x]<<endl;
if(dist[t] == 5)
return 0;
string cur=vis[t];
int l=cur.length();
for(int i = 1;i <= cnt;i++)
{
for(int j = 0;j < l;)
{
string tmp=cur;
int pos=tmp.find(a[i],j);
if(pos == string::npos)break;
j = pos+1;
tmp.erase(pos,a[i].length());
tmp.insert(pos,b[i]);
if(mp.find(tmp)==mp.end())
{
mp[tmp]=n;
vis[n]=tmp;
dist[n]=dist[t]+1;
q.push(n);n ++ ;
}
else if(dist[mp[tmp]]==-1)
{
dist[mp[tmp]]=dist[t]+1;
q.push(n);
}
}
}
}
return 0;
}
void solve()
{
cin>>st>>ed;
// V<V<int>>mp(n+1,V<int>(m+1));
memset(distA,-1,sizeof distA);
memset(distB,-1,sizeof distB);
cnt = 1;
while(cin>>a[cnt]>>b[cnt]) { cnt ++ ;}
int m1 = bfs(st,distA,a,b);
int m2 = bfs(ed,distB,b,a);
int ans = 1000;
for(int i = 0;i<=n;i++) {
if(distA[i] != -1 && distB[i] != -1) {
ans = min(ans,distA[i] + distB[i]);
}
}
if(ans > 10) cout<<"NO ANSWER!"<<endl;
else cout<<ans;
}
signed main(){
clapping();TLE;
// int t;cin>>t;while(t -- )
solve();
// {solve(); }
return 0;
}
/*样例区
*/
//------------------------------------------------------------