[IOI2008] Type Printer 打印機
阿新 • • 發佈:2019-01-06
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]; structTrie { 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 打印機