• 单词接龙(字符串+搜索)


    传送门

    题意:给你n个字符串和一个字符,每个字符串最多使用两次,通过两字符串首尾相接,求出以该字符开头的最长的字符串.

    分析:基本思路是搜索,这个应该不难看出.难点在于对于很多细节的处理,比如"龙"与单词的重叠部分的处理等等.

    int n,ans,used[21];
    string start,word[21];
    //判断我当前要接到"龙"尾的单词:
    //该单词的"头"与"龙"的尾能够重合(即相同)的长度
    bool check(string s,string ss,int k){
        int len=s.size();
        for(int i=0;i<k;i++)
        	if(s[len-k+i]!=ss[i])return false;
        return true;
    }
    //拼接操作
    void add(string &s,string ss,int k){
        int len=ss.size();
        for(int i=k;i<len;i++)
        	s+=ss[i];
    }	
    void dfs(string now){//now表示已经连接起来的"龙"
        int len=now.size();//len当前"龙"的长度
        ans=max(ans,len);//更新答案
        for(int i=1;i<=n;i++){
        	if(used[i]==2)continue;//最多用两次
        	int k=word[i].size();//单词长度
        	for(int j=k;j>=1;j--){
    //长度从大到小判断能否相接,这里有人说长度应该从小到大枚举,接得越少越好
    //但是拼接的前提不应该是保证能接的完全接上吗?(洛谷数据太水,两种写法都能过)
    //check当前的"龙"now,与枚举到的单词word[i],
    //是否头尾j位是相同的,
            	if(check(now,word[i],j)){
            		string temp=now;
            		add(temp,word[i],j);//接起来
            		if(temp==now)continue;
    //接上该单词后,"龙"的长度不变,根据最优性原理,没必要
            		used[i]++;
    //如果可以接上,该单词使用次数加1
            		dfs(temp);//继续搜下去
            		used[i]--;//回溯
            	}
        	}
        }
    }
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++)
        	cin>>word[i];//读入n个单词
        cin>>start;//读入"龙"头
        dfs(start);//直接从"龙"头开始搜索
        cout<<ans<<endl;
        return 0;
    }
    
    

    总结:有关字符串的搜索题,思维难度不会很大,就是要细心,细节特别多,坑特别多.

  • 相关阅读:
    【BZOJ 3732】 Network
    【BJOI 2018】 求和
    【HDU 1005】 Number Sequence
    【HDU 3652】 B-numbers
    【SCOI 2007】 降雨量
    BZOJ2186 SDOI2008沙拉公主的困惑(数论)
    #38 游戏(线段树)
    BZOJ2339 HNOI2011卡农(动态规划+组合数学)
    BZOJ3107 CQOI2013二进制A+B(动态规划)
    BZOJ3083 遥远的国度(树链剖分+线段树)
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10335687.html
Copyright © 2020-2023  润新知