zoukankan      html  css  js  c++  java
  • P1032 字串变换

    题目描述

    已知有两个字串 A, B 及一组字串变换的规则(至多6个规则):

    A1 -> B1

    A2 -> B2

    规则的含义为:在 A$中的子串 A1 可以变换为 B1、A2 可以变换为 B2 …。

    例如:A='abcd'B='xyz'

    变换规则为:

    ‘abc’->‘xu’‘ud’->‘y’‘y’->‘yz’

    则此时,A 可以经过一系列的变换变为 B,其变换的过程为:

    ‘abcd’->‘xud’->‘xy’->‘xyz’

    共进行了三次变换,使得 A 变换为B。

    输入输出格式

    输入格式:

    输入格式如下:

    A B A1 B1

    A2 B2 |-> 变换规则

    ... ... /

    所有字符串长度的上限为 20。

    输出格式:

    输出至屏幕。格式如下:

    若在 10 步(包含 10步)以内能将 A 变换为 B ,则输出最少的变换步数;否则输出"NO ANSWER!"

    输入输出样例

    输入样例#1:
    abcd xyz
    abc xu
    ud y
    y yz
    
    输出样例#1: 
    3
    

    Solution:

    先看一波STL之string详解

    然后本题直接搜嘛,广搜可以,深搜也行,还可以迭代深搜,我用的是dfs。思路比较简单,先用map建立一个string到int的映射,然后对每种变化方式不断在原字符串中查找出现的位置,并进行变化继续深搜。然后就是对于步数超过10的直接剪枝(注意ans不超过10),再加入一条可行性剪枝用最少或最多的变换在剩余的不超过10步的步数中依然大于或无法达到目标字符串的长度,直接减枝,最后输出map映射的目标串的步数就ok咯。

    代码:

    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define debug printf("%d %s
    ",__LINE__,__FUNCTION__)
    using namespace std;
    const int mod = 998244353;
    string s,e,a[20],b[20];
    int lena[20],lenb[20],cnt=1,mx=0,mn=0;
    map<string,int>m;
    il void dfs(string x,int k){
        //debug;
        if(k>=10)return;
        int v=x.size(),p=e.size();
        if((v+mx*(10-k)<p)||(v+mn*(10-k)>p))return;
        k++;
        for(int i=1;i<=cnt;i++){
            int pos=x.find(a[i],0);
            while(pos!=string::npos){
                string tmp=x;
                tmp.replace(pos,lena[i],b[i]);
                if((!m[tmp]&&tmp!=s)||(m[tmp]>m[x]+1))
                    m[tmp]=m[x]+1,dfs(tmp,k);
                pos=x.find(a[i],pos+1);
            }
        }
    } 
    int main()
    {
        ios::sync_with_stdio(0);
        cin>>s>>e;
        while(cin>>a[cnt]>>b[cnt]){
            lena[cnt]=a[cnt].size();
            lenb[cnt]=b[cnt].size();
            mn=min(mn,lenb[cnt]-lena[cnt]);
            mx=max(mx,lenb[cnt]-lena[cnt]);
            cnt++;
            if(cnt>6)break;
        }
        cnt--;
        dfs(s,0);
        if(m[e])cout<<m[e];
        else cout<<"NO ANSWER!";
        return 0;
    }
  • 相关阅读:
    104. 二叉树的最大深度
    Shopping HDU
    Fibonacci again and again HDU
    Brave Game HDU
    Being a Good Boy in Spring Festival HDU
    88. 合并两个有序数组
    26. 删除排序数组中的重复项
    快速幂
    Rectangles(2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1))扫描线+线段树
    Liars(2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1))差分法
  • 原文地址:https://www.cnblogs.com/five20/p/8557525.html
Copyright © 2011-2022 走看看