喵喵的IDE
Problem Description
喵喵有一个神奇的IDE,这个IDE自带一个cache,还有一个当前编辑区editarea,初始的时候这个 cache 中有一个字符串 cachebegin。
喵喵想打按照顺序打N个字符串 x,她可以进行三种操作。
打之前 editarea 为空
1、从cache中拿出一个字符串 B直接赋值给editarea , editarea = B.(如果不拿那么不计入操作数)
2、如果editarea里面有字符,那wuyiqi可以删除掉editarea中最后一个字符。(删光了之后就不能删除啦!)
3、喵喵可以在editarea末尾插入一个任意字符。
如果editarea的字符串恰好与她要打的第i个字符串相同,那么她就完成了这次打印,并且这个字符串自动加入cache(cache中可能出现重复字符串),然后editarea自动清空。那么喵喵就会自动进入下一个字符串的打印阶段。
她想问,对于每次字符串输出,最少需要多少次操作。
1 ≤ N ≤ 105 , 字符串长度总和 ∑(Ai) <106 , cache_begin 长度< 100
Input
第一行一个整数T,代表数据组数。
对于每组数据第一行一个整数 N 代表要打印的字符串个数,还有一个字符串cachebegin
以下N 行每行一个字符串 Ai
Ai 和 cachebegin 都只包含小写字母
Output
Sample Input
1 3 a a ab abc
Sample Output
1 2 2
Hint
一开始cache中为{"a"}
第一次操作直接拿出来{"a"}就好了
现在cache为{"a","a"}
拿出来"a",加入b,两次操作。
现在cache为{"a" , "a" , "ab"}
拿出来"ab",加入c。两次操作
第一次可以从缓存中拿出字符串进行操作,删除末尾字符或者在末尾加入任意字符,使得最小步数获得新的字符串并加入缓存中。用字典树(trie)来存储字符串并进行查找,注意,字典树构建内存分配必须是连续的还是怎样。trie.v表示从当前位置到末尾还有多少个字符。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
struct trie
{
trie * son[26];
int v;
trie()
{
for (int i=0;i<26;i++)
son[i]=NULL;v=0;
}
}*root,k[1000010];
int t=0;
char a[1000010];
void insert(trie *rt,int l)
{
for (int i=0;i<l;i++)
{
int c=a[i]-'a';
if (rt->son[c]==NULL)
{
k[++t]=trie();
rt->son[c]=&k[t];
rt->son[c]->v=l-1-i;
}
else
if (rt->son[c]->v>l-1-i)
rt->son[c]->v=l-1-i;
rt=rt->son[c];
}
}
int getanswer(trie * rt,int l)
{
int ans=l;
for (int i=0;i<l;i++)
{
int c=a[i]-'a';
if (rt->son[c]==NULL) break;
else
{
if (ans>rt->son[c]->v+l-i)
ans=rt->son[c]->v+l-i;
}
rt=rt->son[c];
}
return ans;
}
int main()
{
int T,n;
scanf("%d",&T);
while (T--)
{
t=-1;
scanf("%d %s",&n,a);
k[++t]=trie();
root=&k[t];
int l=strlen(a);
insert(root,l);
while (n--)
{
scanf("%s",a);
l=strlen(a);
int ans=getanswer(root,l);
insert(root,l);
printf("%d\n",ans);
}
}
return 0;
}
上个版本太渣了,内存容易爆栈。来个用new新建内存的方案。顺便把原题附上:http://hihocoder.com/contest/hiho2/rank
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
struct trie
{
trie * son[30];
int v[30];
trie()
{
for (int i=0;i<30;i++)
{
son[i]=NULL;
v[i]=0;
}
}
}*root;
int t,n;
char s[30];
void insert(trie * rt,int l)
{
for (int i=0;i<l;i++)
{
int c=s[i]-'a';
if (rt->son[c]==NULL)
{
trie *rit=new trie();
rt->son[c]=rit;
rt->son[c]->v[c]=1;
}
else rt->son[c]->v[c]++;
rt=rt->son[c];
}
}
int getans(trie * rt,int l)
{
int ans=0;
for (int i=0;i<l;i++)
{
int c=s[i]-'a';
if (rt->son[c]==NULL) return 0;
else ans=rt->son[c]->v[c];
rt=rt->son[c];
}
return ans;
}
/*void del(trie * root)
{
for(int i=0;i<30;i++)
{
if(root->son[i]!=NULL)
del(root->son[i]);
}
free(root);
}*/
int main()
{
scanf("%d",&n);
t=0;
root=new trie();
getchar();
for (int i=0;i<n;i++)
{
scanf("%s",&s);
int l=strlen(s);
insert(root,l);
}
scanf("%d",&n);
getchar();
for (int i=0;i<n;i++)
{
scanf("%s",&s);
int l=strlen(s);
printf("%d\n",getans(root,l));
}
delete root;
// del(root);
return 0;
}

1374

被折叠的 条评论
为什么被折叠?



