1 条题解

  • 0
    @ 2026-10-25 21:41:05

    思路

    合并历史为AC状态与已覆盖模式位集,按字符递增进行BFS并只保留首次到达即可同时实现最短和最小字典序;最多601×4096状态,父指针回溯不保存每条路径字符串;重复词及fail输出位均须处理。

    参考程序(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int n;cin>>n;vector<array<int,26>>g(1);vector<int>f(1),out(1);set<int>alphabet;for(int i=0;i<n;i++){string s;cin>>s;int v=0;for(char c:s){int x=c-'A';alphabet.insert(x);if(!g[v][x]){int u=g.size();g[v][x]=u;g.push_back({});f.push_back(0);out.push_back(0);}v=g[v][x];}out[v]|=1<<i;}queue<int>q;for(int c:alphabet)if(g[0][c])q.push(g[0][c]);while(!q.empty()){int v=q.front();q.pop();out[v]|=out[f[v]];for(int c:alphabet)if(g[v][c]){int u=g[v][c];f[u]=g[f[v]][c];q.push(u);}else g[v][c]=g[f[v]][c];}int nodes=g.size(),full=(1<<n)-1,total=nodes*(1<<n);vector<int>prev(total,-2),que;vector<unsigned char>letter(total);que.reserve(total);prev[0]=-1;que.push_back(0);int goal=-1;for(size_t h=0;h<que.size()&&goal<0;h++){int id=que[h],v=id%nodes,mask=id/nodes;for(int c:alphabet){int u=g[v][c],m=mask|out[u],next=m*nodes+u;if(prev[next]!=-2)continue;prev[next]=id;letter[next]=c;que.push_back(next);if(m==full){goal=next;break;}}}string ans;for(int id=goal;prev[id]!=-1;id=prev[id])ans+=char('A'+letter[id]);reverse(ans.begin(),ans.end());cout<<ans<<'\n';}
    
    • 1

    信息

    ID
    1536
    时间
    1000ms
    内存
    64MiB
    难度
    提高
    标签
    递交数
    1
    已通过
    1
    上传者