codeforces 633 C. Spy Syndrome 2(字典树)

https://codeforces.com/contest/633/problem/C
题意:
一个密码,由很多单词分别进行操作后,连接而成。操作如下 :
先翻转,然后全部变为小写字母,最后消去单词间空格,连接成密码。 现给你一些单词和一个密码,将密码换成原来字典上的单词

思路:直接逆序将所有单词插入到字典树中,直接回朔法dfs,判断是否能以该字母作为结尾,然后继续判断下一单词是否存在

#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define fi first
#define se second
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
using namespace std;
 
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> LP;
const ll inf = 0x3f3f3f3f;
const int N = 1e6 + 10;
const ll mod = 10007;
const int base=131;
tr1::unordered_map<ll,ll> mp;
 
ll n,m,id,x,y,k,q,cnt,flag;
ll num[1000000];//单词出现次数
ll tree[N][27];//tree[i][j]表示节点i的第j个儿子的节点编号
ll tot;//总结点数
string s;
int ans[N];
string t[N];
void ins(string str,int id)
{
	int root=0;
	int l=str.size();
	for(int i=l-1;i>=0;i--)
	{
		str[i]=tolower(str[i]);//这里注意换小写
		int id=str[i]-'a';
		if(!tree[root][id]) tree[root][id]=++tot;
		root=tree[root][id];
 
	}
	num[root]=id;//单词结尾标记下标
}
int dfs(int x)
{
	if(x==n)
	{
		for(int i=1;i<=cnt;i++)
			cout<<t[ans[i]]<<" ";
		flag=1;
		return 1;
	}
	if(flag) return 1;
	int root=0;
	for(int i=x;i<n;i++)//枚举每个字母作为结尾
	{
		int id=s[i]-'a';
		root=tree[root][id];
 
		if(!root) return 0;//如果该字母此路径上不存在 错误
		if(num[root])//枚举结尾单词
		{
			ans[++cnt]=num[root];
			if(dfs(i+1))
			{
				return 1;
			}
			cnt--;
 
		}
	}
}
int main() {
 
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
 
	cin>>n;
	cin>>s;
	cin>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>t[i];
		ins(t[i],i);
	}
	dfs(0);
 
 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值