洛谷 P1032 字串變換題解

題目連接:https://www.luogu.org/problem/P1032html

題目描述

已知有兩個字串A,BA,B及一組字串變換的規則(至多66個規則):ios

A_1A1 ->B_1B1數組

A_2A2 -> B_2B2測試

規則的含義爲:在 AA中的子串 A_1A1 能夠變換爲B_1B1A_2A2 能夠變換爲 B_2B2 …。spa

例如:A=abcd,B=xyzcode

變換規則爲:orm

abcxuudyyyzhtm

則此時,AA能夠通過一系列的變換變爲BB,其變換的過程爲:blog

abcdxudxyxyzci

共進行了33次變換,使得AA變換爲BB。

輸入格式

輸入格式以下:

ABB
A_1A1 B_1B1
A_2A2 B_2B2 |-> 變換規則

... ... /

全部字符串長度的上限爲2020。

輸出格式

輸出至屏幕。格式以下:

若在1010步(包含1010步)之內能將AA變換爲BB,則輸出最少的變換步數;不然輸出"NO ANSWER!"

輸入輸出樣例

輸入 #1
abcd xyz
abc xu
ud y
y yz
輸出 #1
3

題解

這是一個字符串操做的BFS。和前面作過的01迷宮馬的遍歷相比,每次變化就至關於一次移動,而變換先後的字符串就至關於迷宮中的格點。使用STL中的string類進行find和replace操做仍是至關方便的。在前面的例題中使用bool數組來描述是否遍歷過某個格點,而這裏使用一個map數組來描述是否遍歷過某個字符串操做結果。下面是代碼。

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <map>

using namespace std;

struct Node
{
    string x;
    int step;
};
Node q[100005];

const int MAXN = 1005;
int cnt = 0, step, front, rear; 
string n, m, a[MAXN], b[MAXN];
map<string, bool> vis; //做用等同於數組中的vis數組 

int bfs()
{
    Node now;
    now.x = n;
    now.step = 0;
    front = rear = 0;
    q[rear] = now;
    rear++;
    while(front < rear)
    {
        now = q[front++];
        if(now.x == m)
        {
            cout << now.step << endl;
            return 0;
        }
        if(now.step > 10)
        {
            return -1;
        }
        for(int i = 0; i < cnt; i++)
        {
            string temp = now.x;
            int pos = temp.find(a[i]);
            while(pos != -1) 
            {
                temp.replace(pos, a[i].length(), b[i]); //作變換 = pos 
                if(vis[temp] == 0) 
                {
                    vis[temp] = true;
                    q[rear].x = temp;
                    q[rear].step = now.step + 1;
                    rear++;
                }
                temp = now.x; 
                pos = temp.find(a[i], pos + 1); // 從下一個位置查找,作一次變換
            }
        } 
    }
    return -1;
}
    
int main()
{
    cin >> n >> m;
    cnt = 0;
    while(cin >> a[cnt] >> b[cnt])
    {
        cnt++;
    }
    if(bfs() < 0)
    {
        cout << "NO ANSWER!" << endl;
    }
    return 0;
}

程序裏面另一個須要注意的是,A字符串中可能存在多個變換的子串,咱們須要每次變換其中的一個。有一個測試例是專門卡這種狀況的:

abaaaba abcdabaa bb dd ee ff gg c

相關文章
相關標籤/搜索