Codevs 1251 括号 解题报告

我的第一篇解题报告( -。- )  

原题点这里

括号,这是一道普通的DFS+字符串处理题,但对于与我这种平时不怎么碰STL的人来说,光是看题解就足足看了半个小时(我有多弱就不解释了吧),最后硬是照着别人的题解才勉强打出来了。


但说实话,这道题带给我的小知识倒真的不少,可以简单的在这列一下(如果有和我一样的难兄难弟可以一起看一下哦!)


    1. vector的下标是从 0 开始记录的,而它的size函数则是返回vector内的元素个数,其意是:当你只用push_back函数无脑存储元素时,应当从 0 一直枚举到 size-1 !


    2.vector是可以直接用下标访问的!(在代码中可以看到)


    3.string可以直接用相加的方式(+) 来合成串!(同样也可以在代码中看到)


     4.函数的返回值居然若此多样!



题目分析

    这是一道喊你添加括号的DFS题,那么首当其冲的一步,就是应该先知道怎样添加括号,于是乎,我们觉醒了在小学时学习乘法时的各种经验,便一下得出了以下结论

   1. 对于单独的两个元素(比如 “z" 和 “b”,它们都是在题目中直接给出的数据),要把它们组合成一个串(至少包含两个元素),那么会有:(z*b)

    2. 对于一个单独的元素(还是“z“)与一个串(比如简称它为 “h”)要把它们组合成一个更大的串,那么会有:(zh)

    3.同2, 对于一个串和另一个串(比如为“c”和“h”),要把它们组合成一个更大的串,那么会有(ch)

         

   然后,在得到了这个结论以后,这一切就没什么好说了,我们的任务就是用DFS顺序来切割子串,贴上借鉴大神的程序,努力分析,一起提升吧(真的是一起么...)

    

#include<vector>
#include<cstring>
#include<iostream>
using namespace std;

const int N=10+5;

string str[N];

int n; 

vector<string> Dfs(int l,int r){  // 返回值是vector,存放的是当前括号分割下的所有复合串,然后继续搜索,找出所有可能 
                                  // Dfs(l,r)表示寻找用在(l,r)的数据集合内括号分割所有可能串,而(1,n)即是我们的最终答案 
    vector<string> v;
    
    if ( l==r ){ // 特殊情况1:只有一个元素  
    
        v.push_back(str[l]);   
        return v;
     
    }    
    
    if ( l+1==r ){ // 特殊情况2:是两个元素结合成串 (即结论1) 
    
       string s="("+str[l]+"*"+str[r]+")"; 
       v.push_back(s);
       return v;
     
    }
    
    // 正常情况:串与串 或 元素与串 结合(即结论2,3)  
    for(int cut=l;cut<r;cut++){
    
        vector<string> left=Dfs(l,cut);
        vector<string> right=Dfs(cut+1,r);
        
        for(int i=0;i<left.size();i++)
          for(int j=0;j<right.size();j++){  // 下标有毒,小心 
          
              string s="("+left[i]+right[j]+")";
              v.push_back(s);
            
          }// 这里可能会误导大家,但这只是枚举每个左子串和右子串,将它们两两结合,生成所有可能的复合串的操作罢了   
          
    }    
    
    return v;

}

int main(){

    cin>>n;
    
    for(int i=1;i<=n;i++) cin>>str[i]; // 读入数据串 

    vector<string> ans=Dfs(1,n); // vector里存放了所有满足括号分割的复合串 
    
    for(int i=0;i<ans.size();i++) cout<<ans[i]<<"\n";  
    
  return 0;

}

或许下一次我不会写这么多了吧,额嘿嘿(真的多么...)


2017.1.28




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值