The ABCD Murderer
思路
首先用ac自动机找到每一个点能向前最早到哪里,然后进行匹配就可以了
代码
//就是要用多少单词可以拼出这个单词 //这个CF有一个简化版 //当时是使用暴力过去的 //每次旋转一个最长的就可以了 //从后面开始选择,选一个最长的就可以了 #include <bits/stdc++.h> using namespace std; const int M=3e5+5; int ch[M][26],fail[M],cnt[M],tot; void insert(string s) { int p=0,n=s.length(); for(int i=0;i<n;i++) { int v=s[i]-'a'; if(ch[p][v]==0)ch[p][v]=++tot; p=ch[p][v]; } cnt[p]=max(cnt[p],n); }//要不就直接记录长度吧 int last[M]; void build() { queue<int>q; for(int i=0;i<26;i++) if(ch[0][i])q.push(ch[0][i]); while(!q.empty()) { int now=q.front(); q.pop(); for(int i=0;i<26;i++) { if(ch[now][i]) { fail[ch[now][i]]=ch[fail[now]][i]; q.push(ch[now][i]); if(cnt[fail[ch[now][i]]])last[ch[now][i]]=fail[ch[now][i]]; else last[ch[now][i]]=last[fail[ch[now][i]]]; } else ch[now][i]=ch[fail[now]][i]; } } } int a[M]; void query(string s) { int now=0,n=s.length(); for(int i=0;i<n;i++) { now=ch[now][s[i]-'a']; for(int j=now;j;j=last[j]) if(cnt[j]) { a[i]=i-cnt[j]+1;//能够达到哪里 break; } } } int main() { memset(a,0x3f,sizeof(a)); int n;cin>>n; string s;cin>>s; for(int i=1;i<=n;i++) { string t;cin>>t; insert(t); } build(); query(s); n=s.length(); int l=a[n-1],r=n-2; int ans=1; while(1) { if(l==0)break; int tmp=n; for(int i=r;i>=l-1;i--) tmp=min(tmp,a[i]); r=l-1; l=tmp; if(tmp==n)return cout<<-1,0; ans++; } cout<<ans<<endl; return 0; } //直接找就行了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现