【dfs】P1019 [NOIP2000 提高组] 单词接龙

        P1019 [NOIP2000 提高组] 单词接龙

原本应该不是一道难题,因为奇特的理解wa了三次,记录一下。

        题目要求最长的龙,有以下几点需要注意:
        1.单词可以使用两次,因此存在自己连接自己的情况,不要想当然的。        

        2.后缀与前缀的公共部分取最小。

        3.重叠部分不能存在包含关系。

  

解决办法还是比较好想的,对两两单词的连接部分进行预处理(注意自己和自己),然后使用深度搜索,对每个可行答案进行判断。

#include<cstdio> 
#include<iostream>
#include<algorithm>
#include<cstring>
#include <stack>
#define LL long long

using namespace std;
const int N = 1e6 + 10;
int vis[30],chk[21][21],n,ans=0;
string s[21];
char m;
int ll(int a,int b){
	int la=s[a].length(),lb=s[b].length();
	int len=min(la,lb);
	for(int i = 1; i < len; i++) {//重叠长度从1开始,直到最短的字符串长度-1(因为不能包含)
		int flag = 1;
		for(int j = 0; j < i; j++)
			if(s[a][la - i + j] != s[b][j]) flag = 0;
		if(flag) return i;//检测完毕相等则立即return
	}
	return 0;
}
void check(){
	int len1,len2;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			chk[i][j]=ll(i,j);
			//cout<<chk[i][j]<<' ';
		}
	}
}

void dfs(int k,int len){
	int l=0;
	for(int i=1;i<=n;i++){
		if(vis[i]<2&&chk[k][i]>0){
			vis[i]++;
			dfs(i,len+s[i].length()-chk[k][i]);
			vis[i]--;
		}
	}
	ans=max(ans,len);
	return ;
}


int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>s[i];
	}
	cin>>m;
	check();
	for(int i=1;i<=n;i++){
		if(m==s[i][0]) {
			vis[i]++;
			dfs(i,s[i].length());
			vis[i]--;
		}
	}
	cout<<ans;
	return 0; 
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值