1. 程式人生 > >洛谷P1032 字串變換

洛谷P1032 字串變換

退出 bool visit 枚舉 子串 put find 用法 輸出

題意:將一個字符串從初始狀態變換為目標狀態,最多有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;
}

洛谷P1032 字串變換