洛古 P1019 单词接龙 DFS

dfs

刚开始卡了一段

纠结怎么用字符串添加再回溯

确实没啥思路

后来发现把题目完全转换为可以后接的数字矩阵就会简单很多

然后dfs

对我而言dfs的本质是

先写生成全排列的框架

然后加上判定条件和回溯

即可解决问题

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

const int MAXN = 2e1 + 10;

int prefix[MAXN][MAXN] = {0}, used[MAXN] = {0}; 
int N, ans = 0;

string mode[MAXN];

void preoprt(int x, int y)	//预处理 
{
	int lena = mode[x].length() - 1, lenb = mode[y].length() - 1;
	
	for(int i = 0; i < lenb; i++)
	{
		if(mode[y][i] == mode[x][lena]) //寻找后串里每一个等于前串最后一个的字符 
		{
			bool flag = true;
			if(lena > i) //如果包含就舍去 
			{
				for(int j = i; j >= 0; j--)//判断是否能从该位向前拼接 
				{
					if(mode[x][lena - j] != mode[y][i - j])
						flag = false;
				}
				if(flag)
				{
					prefix[x][y] = lenb - i; //构建二维拼接数组 prefix[a][b] 存a接b应加长度 
					
					goto l1;
				}	
			}
			
		}
	}	
	
	l1:
		return ;
}

void dfs(int ret, int len)
{	
	used[ret]++;
	
	ans = max(ans, len); //寻值 
	
	for(int i = 0; i < N; i++)
	{
		if(used[i] <= 1 && prefix[ret][i] > 0)		
		{
			dfs(i, len + prefix[ret][i]);
			
			used[i] --; //回溯 
		}	
	} 
}

int main()
{
	cin>>N;
	
	char head;
	
	for(int i = 0; i < N; i++)
		cin>>mode[i];
	
	cin>>head;
	
	for(int i = 0; i < N; i++)
	{
		for(int j = 0; j < N; j++)
		{
			preoprt(i, j);//预处理 
		}
	}
	
	
	for(int i = 0; i < N; i++)
	{	
		dfs(i, mode[i].length());
	}
	
	cout<<ans<<endl;
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Zeolim/article/details/81067969