Wikioi 1018 单词接龙

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

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

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

5

at

touch

cheat

choose

tact

a

 

23    

(连成的“龙”为atoucheatactactouchoose)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,con[21][21],visited[21],ans;
char dict [21][110],st;
int lenn (int a,int b)//处理a单词后面连b单词,其中的重叠部分
{
    int len1=strlen(dict[a]),len2=strlen(dict[b]);
    for (int i=len1-1;i>0;i--)
    {
        if (len1-i==len2)break;
        bool flag=1;int kount=0;
    	for (int j=i;j<len1;j++)
        {    
            //printf ("%c %c\n",dict[a][j],dict[b][j-i]);
         	if (dict[a][j]!=dict[b][j-i])flag=0;
        }
        if (flag){/*printf ("%s %s %d\n",dict[a],dict[b],len1-i);*/return con[a][b]=len1-i;}
    }
    //printf ("%s %s 0\n",dict[a],dict[b]);
    return 0;
}
void dfs (int a,int len)// dfs (a,len)表示当前状态中最后一个单词是a,龙长度是len
{
    //printf ("%s %d\n",dict[a],len);
	bool flag=1;
    for (int i=1;i<=n;i++)
        if (con[a][i] && visited[i]<2)
    	{	visited[i]++;dfs(i,len+strlen(dict[i])-con[a][i]);visited[i]--;flag=0;	}
    if (flag)ans=max(ans,len);
    //printf ("return\n");return;
}
int main ()
{
    scanf ("%d",&n);
    for (int i=1;i<=n;i++)
    {   scanf ("%s\n",dict[i]);/*printf ("%d %s\n",i,dict[i]);*/}
    scanf ("%c",&st);//printf ("%c\n",st);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
        	lenn(i,j);
    for (int i=1;i<=n;i++)//可以开始深搜的话就开始。。
        if (dict[i][0]==st)
    	{	memset (visited,0,sizeof(visited));visited[i]++;dfs (i,strlen(dict[i]));/*printf ("----------\n");*/}
    //printf ("%d\n",lenn(1,1));
    //printf ("con[5][4]=%d\n",con[5][4]);
    printf ("%d\n",ans);
	return 0;
}

//Copyright (C) 2014 wikioi user12923 All rights reserved  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值