练习赛20160319赛后总结

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.

你可能感兴趣的:(练习赛20160319赛后总结)