洛谷P1032 字串變換
阿新 • • 發佈:2019-01-30
退出 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 字串變換