【题解】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;
}
posted @ 2022-10-31 11:40  watasky  阅读(36)  评论(0编辑  收藏  举报