• 字串变换(字符串+搜索剪枝)


    题意:将一个字符串从初始状态变换为目标状态,最多有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
    ",ans.front());
        return 0;
    }
    
    
  • 相关阅读:
    关于值传递和引用传递
    单例设计模式(创建型模式)
    逻辑分页和物理分页
    java基本数据类型
    Keepalived笔记
    lvs,HAProxy,nginx简单笔记
    限流, 熔断,降级笔记
    redis事务之watch
    Redis-Sentinel
    正式入驻博客园
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10335967.html
Copyright © 2020-2023  润新知