luogu1019:单词接龙:深搜+单词拼接

题目连接:该题是luogu试炼场的2-7:T2


题目大意:
1 给出n,n个单词,首尾有重复就可以拼接在一起,要求如下:
2 每个单词只能最多用2次,单词之间不能完全包含。
3 求:最大的拼接长度。


解题思路:
1 吃果果的深搜,关键是要处理好:单词之间不能完全被包含
2 每个单词可以用2次,记得哦;
3细节请看代码,有详尽的注解


上代码:

//luogu1019:单词接龙
//单词拼接问题:每种情况都是一次;
 
#include<bits/stdc++.h>
using namespace std;

int n,b[50],l[50],su,ans=0;
char s[50][10005],st;
int d[50];

int pd(int x,int y)//判断:x和y能否拼接
{
	int su,kk;
	if(l[x]>=l[y])//前长 
	{
		for(int tou=l[x];tou>=l[x]-l[y]+2;tou--)//从后往前尝试拼接 
		{
			kk=0;
			//s[x][i] vs s[y][j] 
			for(int i=tou,j=1;i<=l[x];i++,j++)
			{
				if(s[x][i]!=s[y][j])
				{
					break;
				}
				kk++;//计数器 
			}
			if(kk==l[x]-tou+1) return l[y]-kk;//kk是匹配的数量 
		}
		return -1;	
	}
	else//后长 
	{
		for(int tou=l[x];tou>=2;tou--)
		{
			kk=0;
			for(int i=tou,j=1;i<=l[x];i++)
			{
				if(s[x][i]!=s[y][j])
				{
					break;
				}
				j++; kk++;
			}
			if(kk==l[x]-tou+1) return l[y]-kk;//kk是匹配的数量 
		}
		return -1;
	} 
}

void dfs(int x,int de)//当前是第x个单词,从第de格开始 
{
	for(int i=1;i<=n;i++)
	{
		int k=pd(x,i);
		
		if(b[i]>0 && k>0)//单词可用&&能拼接 
		{
			b[i]--;su+=k;
			d[de]=i;	
			if(ans<su) ans=su;
		
			dfs(i,de+1);
			
			b[i]++;su-=k;
		}
	}
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",s[i]+1);
		b[i]=2;//每个单词可以拼接 2 次 
		l[i]=strlen(s[i]+1);
	}
	scanf("%s",&st);//龙头 
	
	for(int i=1;i<=n;i++) 
	{ 
		if(s[i][1]==st)//每人都试一下做开头 
		{
			b[i]=1; d[1]=i;
			su=l[i]; //当前的长度 
			if(ans<su) ans=su;//更新答案 
			
			dfs(i,2);//当前是第i个单词,从第2格开始 
			
			b[i]=2; 
		}
	} 
	
	printf("%d",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liusu201601/article/details/89022831