zoukankan      html  css  js  c++  java
  • NOIP2000 单词接龙

    题三.  单词接龙                27分)

     

      问题描述   

        单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。

             

       输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.

             

       只需输出以此字母开头的最长的“龙”的长度

             :

     输入

    5

    at

    touch

    cheat

    choose

    tact

    a

    输出

    23           (连成的“龙”为atoucheatactactouchoose)                                         

    【思路】

      回溯法。

      可以离线求出j接在i之后的重叠部分c[i][j],这样就可以把序列的尾巴u以及序列的长度len作为状态搜索,否则还要以string为状态搜索。

     【代码】

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 
     5 const int maxn = 20+5;
     6 int n;
     7 int c[maxn][maxn];
     8 int x[maxn],A[maxn]; //标记//序列 
     9 string words[maxn];
    10 int wordslen[maxn];
    11 int ans=0;
    12 
    13 //计算a前b后的重叠长度 
    14 //substr截取字符串  
    15 int calc(string a,string b) {
    16     int lena=a.size(),lenb=b.size();
    17     int len=min(lena,lenb);
    18     for(int l=1;l<=len-1;l++) { //len-1不能包含 //且重叠部分尽量小 从小到大枚举 
    19         if(a.substr(lena-l,l)==b.substr(0,l))
    20           return l;
    21     }
    22     return 0;
    23 }
    24 
    25 void dfs(int u,int len) {
    26     ans=max(ans,len); 
    27     for(int v=0;v<n;v++) if(x[v]<2 && c[u][v]) {
    28         x[v]++;
    29         dfs(v,len+wordslen[v]-c[u][v]);
    30         x[v]--;
    31     }
    32 }
    33 int main() {
    34     ios::sync_with_stdio(false);
    35     cin>>n;
    36     for(int i=0;i<n;i++){
    37         cin>>words[i]; wordslen[i]=words[i].size();
    38     }
    39     for(int i=0;i<n;i++) for(int j=0;j<n;j++) //自己可能与自己重叠 
    40        c[i][j]=calc(words[i],words[j]);
    41     char ch; cin>>ch;
    42     for(int i=0;i<n;i++) if(words[i][0]==ch) {
    43         x[i]++; dfs(i,wordslen[i]); x[i]--;
    44     }
    45     cout<<ans;
    46     return 0;
    47 }
  • 相关阅读:
    【新特性速递】卡片式表格,Yeah~~~
    6个最佳DevOps播客
    在裸金属服务器Bare Metal上Kubernetes
    保护Java应用程序不被窃取数据和源代码2
    家政服务行业动态
    15个免费数据集数据科学项目
    性能测试工具
    利用Apache Pulsar的实时边缘计算
    软件开发的八个误解
    如何防止范围蔓延
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4859572.html
Copyright © 2011-2022 走看看