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; }
这道题也是裸的字典树,就是看看构造字典树的时候有没有一条路径的终点在另一条路径上.
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; }
这道题就稍微有点意思.题目的意思就是给你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; }