洛谷P1032 字串变换

题意:将一个字符串从初始状态变换为目标状态,最多有6种变换规则,如果10步之内能完成,输出步数.

分析:又是一道有关字符串的搜索题,思路很简单,把初始状态放入队列里开始跑广搜,枚举所有变换规则,能变就变,变完就入队,队列为空和步数超过10都表示不能完成变换任务.稍微剪下枝就可以了.

int num=1;
string a,b,turna[7],turnb[7];
queue<string> Q;
queue<int> ans;
map<string,int> visit;
bool bfs(){
    while(Q.size()&&Q.front()!=b&&ans.front()<=10){
//如果队列里还有元素,且还没达到目标状态,且步数小于10
        if(visit[Q.front()]){
            Q.pop();ans.pop();
            continue;
        }//剪枝:如果之前这个状态搜索过,就跳过
//枚举num中变换规则:
        for(int i=1;i<=num;i++){
            string s1=Q.front();
            visit[s1]=1;
            while(1){
                int pos=s1.find(turna[i]);
//在要被变换的字符串s1中找是否有可以变换的子串
                if(pos==-1)break;
//找不到就退出,找得到就对s2开始进行变换:
                string s2=Q.front();
                s2.replace(pos,turna[i].size(),turnb[i]);
//熟悉字符串replace的用法:
//从字符串s2的pos下标起,长度为turna[i].size()
//变换为turnb[i]
                Q.push(s2);//变换后入队
                ans.push(ans.front()+1);
                s1[place]='|';
//将s1里子串turna[i]的这次出现位置随便换成另一种字符
//这样就可以查找到s1里子串turna[i]的下一个出现位置
            }
        }
        Q.pop();ans.pop();
    }
    if(!Q.size()||ans.front()>10)return 0;
    return 1;
}
int main(){
    cin>>a>>b;
    Q.push(a);//初始状态入队
    ans.push(0);//初始状态步数为0
//Q队列和ans队列里面的元素一一对应.
    while(cin>>turna[num]>>turnb[num])num++;
    num--;
//读入num种变换规则
    int pd=bfs();
    if(!pd) puts("NO ANSWER!");
    else printf("%d\n",ans.front());
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/PPXppx/p/10335967.html
今日推荐