【题解】P4683 [IOI2008] Type Printer
题目传送门:P4683 [IOI2008] Type Printer
板子题
贪心+字典树+dfs
贪心:把最长的字符留在最后打或者最先打
把每个字母插入字典树
对trie树dfs一遍
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,ch[5000007][28],val[5000007],vis[5000007],f,maxx=-1,cnt,idx;
char s[30000][22],ans[5000007];
inline void insert(char s[])
{
int p=0;
for(int i=0;i<strlen(s);i++)
{
int u=s[i]-'a';
if(!ch[p][u]) ch[p][u]=++idx;
p=ch[p][u];
}
val[p]=1;
}
inline void mark(char s[])
{
int p=0;
for(int i=0;i<strlen(s);i++)
{
int u=s[i]-'a';
p=ch[p][u];
vis[p]=1;
}
}
inline void dfs(int now)
{
if(val[now])
{
ans[++cnt]='P';
}
int flag=-1;
for(int i=0;i<26;i++)
{
int ver=ch[now][i];
if(!ver) continue;
if(vis[ver])
{
flag=i;
}
else
{
ans[++cnt]=i+'a';
dfs(ver);
}
}
if(flag!=-1)
{
ans[++cnt]=flag+'a';
dfs(ch[now][flag]);
}
if(flag==-1&&vis[now])
{
f=1;
}
if(!f) ans[++cnt]='-';
}
int main()
{
scanf("%d",&n);
int tt;
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
int len=strlen(s[i]);
if(len>maxx) maxx=len,tt=i;
insert(s[i]);
}
mark(s[tt]);
dfs(0);
printf("%d\n",cnt);
for(int i=1;i<=cnt;i++)
{
printf("%c\n",ans[i]);
}
return 0;
}