【♂Not The Triumph♂O(∩_∩)O哈哈~But The Struggle♂】

竞赛决不是捷径,它只是另一种艰辛的生活方式。得到与失去,只有时间会去评判;成功与失败,只有历史能去仲裁。我不会永远成功,正如我不会永远失败一样

  C++博客 :: 首页 :: 联系 ::  :: 管理
  6 Posts :: 239 Stories :: 25 Comments :: 0 Trackbacks

常用链接

留言簿(7)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 108466
  • 排名 - 229

最新评论

阅读排行榜

评论排行榜

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

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

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

样例输入:
5
at
touch
cheat
choose
tact
a

输出
23 (连成的“龙”为atoucheatactactouchoose)

分析:
   建立一个无向图,用来保存各个单词之间连接的最大增加长度,glen[i][j]表示i与j连成一个龙是可以增加的最大长度,再进行回溯求出最大长度即可。
   优化:其实是题目中有的,每个单词最多用2次。

【参考程序】:

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

char s[30][300],head;
int glen[30][30],used[30];
int n,ans;
void make_g()
{
    memset(glen,
0,sizeof(glen));
    
int Min,pos,bk;
    
for (int i=1;i<=n;i++)
        
for (int j=1;j<=n;j++)
        {
            
if (strlen(s[i])<strlen(s[j])) Min=strlen(s[i]);
            
else Min=strlen(s[j]);
            
for (int k=1;k<=Min-1;k++)
            {
                bk
=1;
                
for (int t=1;t<=k;t++)
                    
if (s[j][t-1]!=s[i][strlen(s[i])-k+t-1])
                    {
                        bk
=0break;
                    }
                
if (bk)
                {
                    pos
=k; break;
                }
            }
            
if (bk) glen[i][j]=strlen(s[j])-pos;
            
else glen[i][j]=0;
        }
}
void Search(int last,int len)
{
    
if (len>ans) ans=len;
    
for (int j=1;j<=n;j++)
        
if (glen[last][j] && used[j]<2)
        {
            used[j]
++;
            Search(j,len
+glen[last][j]);
            used[j]
--;
        }
}
int main()
{
    scanf(
"%d",&n);
    
for (int i=1;i<=n;i++) scanf("%s",s[i]);
    getchar();
    scanf(
"%c",&head);
    make_g();
    ans
=0;
    memset(used,
0,sizeof(used));
    
for (int i=1;i<=n;i++)
        
if (s[i][0]==head)
        {
            used[i]
=1;
            Search(i,strlen(s[i]));
            used[i]
=0;
        }
    printf(
"%d\n",ans);
    
return 0;
}
posted on 2009-08-20 09:30 开拓者 阅读(909) 评论(0)  编辑 收藏 引用 所属分类: NOIP历届题目

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理