zoukankan      html  css  js  c++  java
  • luogu P1032 字串变换——剪枝

     

    题目描述(在洛谷中查看

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

    A_1A1 -> B_1B1

    A_2A2 -> B_2B2

    规则的含义为:在 AA 中的子串 A_1A1 可以变换为 B_1B1 , A_2A2 可以变换为 B_2B2 …。

    例如: AA =' abcdabcd ' BB =' xyzxyz '

    变换规则为:

    ‘ abcabc ’->‘ xuxu ’‘ udud ’->‘ yy ’‘ yy ’->‘ yzyz ’

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

    ‘ abcdabcd ’->‘ xudxud ’->‘ xyxy ’->‘ xyzxyz ’

    共进行了 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就好,而且我也是做的bfs这板块的题目,结果我却用了dfs(手动捂脸),瞎搞了很大 很大 半天,终于AC!!!
    下面来看一下本蒟蒻的dfs,真的悲催。
     1 #include"iostream"
     2 #include"string"
     3 #include"map"
     4 using namespace std;
     5 const int NoFind = string::npos,NONE = 999999999;
     6 string s_start,s_final,s[10][2];
     7 int min1 = NONE,len,mx,mn = NONE,s_final_len;
     8 map<string,int> ma;
     9 int prune(string &str){
    10     if(str[0] != s_final[0]){
    11         for(int i = 0;i < len;i++){
    12             if(s[i][0][0] == str[0]){
    13                 return false;
    14             }
    15         }
    16         return true;
    17     }
    18     return false;
    19 }
    20 void dfs(string str,int n){
    21     //cout<<str<<' '<<n<<endl;
    22     if(n > 10 || prune(str)){       //剪枝1(减去那些有不可能被替换的首字符的字符串)
    23         return ;
    24     }
    25     if(ma.count(str) == 1){         //剪枝2(减去那些重复的字符串)
    26         return ;
    27     }
    28     int strlen = str.length();
    29     if(mx * (10 - n) + strlen <  s_final_len|| mn * (10 - n) + strlen > s_final_len){       //剪枝3(剪去那些10步内不可能得到的长度)
    30         return ;
    31     }
    32     ma[str] = 1;
    33     if(str == s_final && min1 > n){
    34         min1 = n;
    35         return ;
    36     }
    37     for(int j = 0;j < strlen;j++){
    38         for(int i = 0;i < len;i++){
    39             string s_temp = str;
    40             int pos = s_temp.find(s[i][0],j);
    41             if(pos != NoFind){
    42                 s_temp.replace(pos,s[i][0].length(),s[i][1]);
    43                 dfs(s_temp,n + 1);
    44             }
    45         }
    46     }
    47 }
    48 int main(){
    49     cin>>s_start>>s_final;
    50     cin.get();
    51     s_final_len = s_final.length();
    52     while(cin>>s[len][0]>>s[len][1]){
    53         int len1 = s[len][1].length() - s[len][0].length();
    54         mx = mx > len1 ? mx : len1;
    55         mn = mn < len1 ? mn : len1;
    56         len++;
    57     }
    58     dfs(s_start,0);
    59     if(min1 == NONE){
    60         cout<<"NO ANSWER!";
    61     }
    62     else{
    63         cout<<min1;
    64     }
    65     return 0;
    66 }
  • 相关阅读:
    录音和朗诵的实现
    树型控件的处理(完整版)
    蜘蛛爬虫
    百度公司面试题
    一名程序员的杂想
    javascript语法
    HTML标签
    Winform中保存当前控件的记录
    hdu3079 Vowel Counting (strlwr(将字符串中的字母转换为小写);strupr(转换为大写))
    hdu 1860 统计字符 (水)
  • 原文地址:https://www.cnblogs.com/oleolema/p/9201462.html
Copyright © 2011-2022 走看看