1. 程式人生 > >[IOI2008] Type Printer 打印機

[IOI2008] Type Printer 打印機

turn pri 就是 out while truct node color 技術

技術分享圖片

技術分享圖片

我們考慮如果打印結束時,不允許有部分字母留在打印機內。

這題應該怎麽做

顯然我們將所有要打印的字符串放入一棵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\n",all); for(int i=1;i<=all;i++) printf("%c\n",ans[i]); return 0; }

[IOI2008] Type Printer 打印機