A HDU1711 kmp
很裸的KMP,可怜自己竟然忘了KMP怎么打了...还是理解的不够,用的不够,如果理解得深,用的多了,那应该就不会忘记了0.0...
AC代码:
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#include <math.h>
#include <stack>
#include <iostream>
#include <map>
using namespace std;
int a[1010000];
int b[10100];
int nex[1010000];
int KMP(int n,int m)
{
int l=1,r=0;
nex[1]=0;
while(l<=n)
{
if(r==0||b[l]==b[r])
{
++l;
++r;
nex[l]=r;
}
else r=nex[r];
}
l=1,r=1;
while(l<=n&&r<=m)
{
if(r==0||a[l]==b[r])
++l,++r;
else r=nex[r];
}
if(r>m)
return l-r+1;
return -1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; ++i)
scanf("%d",&a[i]);
for(int i=1; i<=m; ++i)
scanf("%d",&b[i]);
printf("%d\n",KMP(n,m));
}
return 0;
}
B HDU 2087 kmp
这题KMP都不用,直接暴力就行了...
AC代码:
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#include <math.h>
#include <stack>
#include <iostream>
#include <map>
using namespace std;
char a[1010];
char b[1010];
int main()
{
while(~scanf("%s",a))
{
if(a[0]=='#')
break;
scanf("%s",b);
int l=0,la=strlen(a),lb=strlen(b);
int ans=0;
for(int i=0; i<la; ++i)
{
int j;
for(j=0; j<lb; ++j)
if(b[j]!=a[i+j])
break;
if(j==lb)
i+=lb-1,++ans;
}
printf("%d\n",ans);
}
return 0;
}
C HDU 1251 字典树
这题做的我有点懵逼...用动态分配内存的字典树怎么做怎么超内存.没办法只能用静态数组,然后...RE了 TAT 认真看了看数组范围,一退算,我开的数组大小确实不够啊,再加一点....又RE了!!! 好吧,最后改一个极限点的内存,再RE就切题.交了之后发现竟然过了...内存是64640kb O__O "…
AC代码:
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#include <math.h>
#include <stack>
#include <iostream>
#include <map>
using namespace std;
struct lt
{
int count;
int Next[30];
lt()
{
count=0;
memset(Next,0,sizeof(Next));
}
};
lt rt[520000];
int tot=0;
void Insert(int z,char *s,int l)
{
for(int i=0; i<l; ++i)
{
int a=s[i]-'a';
if(!rt[z].Next[a])
rt[z].Next[a]=++tot;
z=rt[z].Next[a];
++rt[z].count;
}
}
int Find(int z,char *s,int l)
{
for(int i=0; i<l; ++i)
{
int a=s[i]-'a';
if(rt[z].Next[a])
z=rt[z].Next[a];
else return 0;
}
return rt[z].count;
}
int main()
{
char s[20];
tot=0;
bool fg=0;
while(gets(s))
{
if(fg)
printf("%d\n",Find(0,s,strlen(s)));
else
{
if(s[0]<'a'||s[0]>'z')
fg=true;
else
Insert(0,s,strlen(s));
}
}
return 0;
}
D HDU 1671 字典树
这道题也是裸的字典树,就是看看构造字典树的时候有没有一条路径的终点在另一条路径上.
AC代码:
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#include <math.h>
#include <stack>
#include <iostream>
#include <map>
using namespace std;
struct lt
{
bool fg;
int ne[11];
};
lt rt[401000];
int tot;
bool Insert(int z,char *s,int l)
{
for(int i=0; i<l; ++i)
{
int a=s[i]-'0';
if(rt[z].ne[a]==0)
rt[z].ne[a]=++tot;
else if(rt[rt[z].ne[a]].fg||i==l-1)
return false;
z=rt[z].ne[a];
}
rt[z].fg=true;
return true;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
tot=0;
memset(rt,0,sizeof(rt));
int n;
char s[100];
bool fg=true;
scanf("%d",&n);
for(int i=0; i<n; ++i)
{
scanf("%s",s);
if(fg)
fg=Insert(0,s,strlen(s));
}
printf("%s\n",fg?"YES":"NO");
}
return 0;
}
E HDU 4287 字典树
这道题就稍微有点意思.题目的意思就是给你n个手机9宫格按键顺序,然后给你m个字符序列,看看那n个按键顺序能匹配多少个字符序列.
只需要把每个字符转成对应的数字,然后再构造字典树就好了.
错了一次,原因是因为我开的是静态数组,然后没有用memset()初始化... TAT 太粗心了啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!
AC代码:
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#include <math.h>
#include <stack>
#include <iostream>
#include <map>
using namespace std;
int huan[130];
void init()
{
huan['a']=huan['b']=huan['c']=2;
huan['d']=huan['e']=huan['f']=3;
huan['g']=huan['h']=huan['i']=4;
huan['j']=huan['k']=huan['l']=5;
huan['m']=huan['n']=huan['o']=6;
huan['p']=huan['q']=huan['r']=huan['s']=7;
huan['t']=huan['u']=huan['v']=8;
huan['w']=huan['y']=huan['x']=huan['z']=9;
}
struct lt
{
int count;
int nex[12];
};
lt rt[50500];
int tot;
void Insert(int z,char *s)
{
for(int i=0; s[i]; ++i)
{
int a=huan[s[i]];
if(rt[z].nex[a]==0)
rt[z].nex[a]=++tot;
z=rt[z].nex[a];
}
++rt[z].count;
}
int Find(int z,char *s)
{
for(int i=0; s[i]; ++i)
{
int a=s[i]-'0';
if(rt[z].nex[a])
z=rt[z].nex[a];
else return 0;
}
return rt[z].count;
}
char a[5050][10];
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
tot=0;
memset(rt,0,sizeof(rt));
int n,m;
scanf("%d%d",&n,&m);
for(int i=0; i<n; ++i)
scanf("%s",a[i]);
for(int i=0; i<m; ++i)
{
char s[10];
scanf("%s",s);
Insert(0,s);
}
for(int i=0; i<n; ++i)
{
printf("%d\n",Find(0,a[i]));
}
}
return 0;
}
F HDU 1434 堆或优先队列
这道题就照着题意用优先队列暴力就好.
AC代码:
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#include <math.h>
#include <stack>
#include <iostream>
#include <map>
using namespace std;
bool scmp(const char *s1,const char *s2)
{
int l1=strlen(s1),l2=strlen(s2),i;
for(i=0; i<l1&&i<l2; ++i)
{
if(s1[i]>s2[i])
return false;
if(s1[i]<s2[i])
return true;
}
if(i==l1)
return true;
return false;
}
struct lt
{
int rp;
char na[23];
bool operator<(const lt& cmp)const
{
if(this->rp==cmp.rp)
return scmp(this->na,cmp.na);
return this->rp>cmp.rp;
}
};
priority_queue<lt>q[10100];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
lt temp;
for(int i=1; i<=n; ++i)
{
while(!q[i].empty())
q[i].pop();
int bj;
scanf("%d",&bj);
for(int j=0; j<bj; ++j)
{
scanf("%s%d",temp.na,&temp.rp);
q[i].push(temp);
}
}
for(int i=0; i<m; ++i)
{
char op[10];
int bi,bj,l;
scanf("%s",op);
l=strlen(op);
if(l==5)
{
scanf("%d%s%d",&bi,temp.na,&temp.rp);
q[bi].push(temp);
}
if(l==4)
{
scanf("%d%d",&bi,&bj);
while(!q[bj].empty())
{
q[bi].push(q[bj].top());
q[bj].pop();
}
}
if(l==6)
{
scanf("%d",&bi);
printf("%s\n",q[bi].top().na);
q[bi].pop();
}
}
}
return 0;
}
这些就是比赛时做出来的题了.和上一次一样,太粗心了TAT.