[IOI2008] Type Printer 打印机

我们考虑如果打印结束时,不允许有部分字母留在打印机内。

这题应该怎么做

显然我们将所有要打印的字符串放入一棵Trie树

那么答案就是Trie树的节点数乘2+m

打印顺序只要沿树走即可

现在我们再来考虑打印结束时,允许有部分字母留在打印机内的情况

我们发现其实就是最后一个单词不用删除

那么我们让最长的一个单词最后输出即可

实现方式为,记录下最长的串后,在Trie树上打上标记

遍历Trie树时,碰到标记就最后访问

此处实现细节较多,要小心谨慎

总体实现如下:

#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef long long ll;
inline int read()
{
    register int p(1),a(0);register char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') p=-1,ch=getchar();
    while(ch>='0'&&ch<='9') a=a*10+ch-48,ch=getchar();
    return a*p;
}
const int N=500010;
int n,tot=0,root,all=0,finish;
char du[N],ji[N],ans[1001000];
struct Trie
{
    int nxt[26];
    bool end,mark;
}tree[N];
int newnode()
{
    ++tot;
    memset(tree[tot].nxt,-1,sizeof(tree[tot].nxt));
    return tot;
}
void insert(char *a)
{
    int cur=root,len=strlen(a+1),idx;
    for(int i=1;i<=len;i++)
    {
        idx=a[i]-'a';
        if(tree[cur].nxt[idx]==-1)
            tree[cur].nxt[idx]=newnode();
        cur=tree[cur].nxt[idx];
    }
    tree[cur].end=1;            
}
void biao(char *a)
{
    int cur=root,len=strlen(a+1),idx;
    for(int i=1;i<=len;i++)
    {
        idx=a[i]-'a';
        cur=tree[cur].nxt[idx];
        tree[cur].mark=1;
    }            
}
void DFS(int xx)
{
    if(tree[xx].end) ans[++all]='P';
    int temp=-1,cur;
    for(int i=0;i<26;i++) if(tree[xx].nxt[i]!=-1)
    {
        cur=tree[xx].nxt[i];
        if(!tree[cur].mark)
        {
            ans[++all]=i+'a';
            DFS(tree[xx].nxt[i]);
        }
        else temp=i;
    }
    if(temp!=-1) ans[++all]=temp+'a',DFS(tree[xx].nxt[temp]);
    if(temp==-1&&tree[xx].mark) finish=1;
    if(!finish) ans[++all]='-';
}
int main()
{
    // freopen("input","r",stdin);
    // freopen("output","w",stdout);
    n=read();
    root=newnode();
    for(int i=1;i<=n;i++)
    {
        scanf("%s",du+1);insert(du);
        if(i==1||strlen(du+1)>strlen(ji+1)) strcpy(ji+1,du+1);        
    }
    biao(ji);
    DFS(root);
    printf("%d
",all);
    for(int i=1;i<=all;i++) printf("%c
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/cold-cold/p/10226718.html