hdu__KMP算法模板题【持续更新中】

hdu 2087 剪花布条

                                                                          Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
                                                                                                        Total Submission(s): 11499    Accepted Submission(s): 7385

                                            链接:
Click me

Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?

  Input 输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。

  Output 输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。

  Sample Input

abcde a3 aaaaaa aa #   Sample Output

0 3  

参考了下面这三位大牛的KMP 的讲解,收获多多。
http://www.ituring.com.cn/article/59881

http://blog.csdn.net/v_july_v/article/details/7041827

http://www.cnblogs.com/mfryf/archive/2012/08/15/2639565.html

#include <queue>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define FIN             freopen("input.txt","r",stdin)
#define FOUT            freopen("output.txt","w",stdout)
#define UFOR(i,a,b)     for(int i = a;i <= b;i++)
#define CASE(T)         int T;for(scanf("%d",&T);T--;)
//typedef __int64  LL;
//typedef long long LL;
const double eps = 1e-10;
const int maxn = 1000+5;
char s[maxn],p[maxn];
int Next[maxn];
void getNext(const char x[],int len)
{
    int i,j;
    j = Next[0] = -1;
    i = 0;
    while(i < len)
    {
        while(-1 != j &&  x[i] != x[j]) j = Next[j];
        ++i,++j;
        if(x[i] == x[j]) Next[i] = Next[j];
        else Next[i] = j;
    }
}
int KMP(const char p[],int plen,const char s[],int slen)
{
    int i,j;
    int ans = 0;
    getNext(p,plen);
    i = j = 0;
    while(i < slen)
    {
        while(-1 != j && s[i] != p[j]) j = Next[j];
        ++i,++j;
        if(j >= plen)
        {
            ans++;
            j = 0;
        }
    }
    return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
    FIN;
#endif // ONLINE_JUDGE
    while(~scanf("%s",s))
    {
        if(s[0] == '#') break;
        scanf("%s",p);
        int ans = KMP(p,strlen(p),s,strlen(s));
        printf("%d\n",ans);
    }
    return 0;
}

hdu 1867 A + B for you again

                                                                  Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
                                                                                           Total Submission(s): 5272    Accepted Submission(s): 1325

                                                                                     链接:
Click me!

Problem Description Generally speaking, there are a lot of problems about strings processing. Now you encounter another such problem. If you get two strings, such as “asdf” and “sdfg”, the result of the addition between them is “asdfg”, for “sdf” is the tail substring of “asdf” and the head substring of the “sdfg” . However, the result comes as “asdfghjk”, when you have to add “asdf” and “ghjk” and guarantee the shortest string first, then the minimum lexicographic second, the same rules for other additions.   Input For each case, there are two strings (the chars selected just form ‘a’ to ‘z’) for you, and each length of theirs won’t exceed 10^5 and won’t be empty.   Output Print the ultimate string by the book.   Sample Input

asdf sdfg asdf ghjk   Sample Output

asdfg asdfghjk

题意:

给定字符串a,b,输出两个字符串连接起来的最小字典序,有个条件,如果字符串s1的某个前缀与s2的某个后缀相同,那么可以把前缀和后缀合并起来,也就是是要输出前缀或者后缀中的一个即可。

#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define FIN             freopen("input.txt","r",stdin)
#define FOUT            freopen("output.txt","w",stdout)
#define CASE(T)         int T;for(scanf("%d",&T);T--;)
const int maxn = 100000+5;
char a[maxn],b[maxn];
int Next[maxn];
void getNext(char x[],int m,int next[])
{
    int i,j;
    j = next[0] = -1, i = 0;
    while(i < m)
    {
        while(-1 != j && x[i] != x[j]) j = next[j];
        ++i, ++j;
        if(x[i] == x[j]) next[i] = next[j];
        else next[i] = j;
    }
}
int KMP(char s[],int slen,char p[],int plen)
{
    int i,j,ans = 0;
    getNext(p,plen,Next);
    i = j = 0;
    while(i < slen)
    {
        while(-1 != j && s[i] != p[j]) j = Next[j];
        ++i,++j;
    }
    return (j == -1) ? 0 : j;
}
int main()
{
#ifndef ONLINE_JUDGE
    FIN;
#endif // ONLINE_JUDGE
    while(~scanf("%s %s",a,b))
    {
        int lab = 0,lba = 0,t;
        int alen = strlen(a), blen = strlen(b);
        t = min(alen,blen);
        lab = KMP(a,alen,b,blen);
        lba = KMP(b,blen,a,alen);
        if(lab > lba)
        {
            a[alen-lab] = '\0';
            printf("%s%s\n",a,b);
        }
        else if(lab < lba)
        {
            b[blen-lba] = '\0';
            printf("%s%s\n",b,a);
        }
        else if(lab == 0)
        {
            string str1(a);str1 += b;
            string str2(b);str2 += a;
            printf("%s\n",min(str1,str2).c_str());
        }
        else
        {
            char t1;
            t1 = a[alen-lab];
            a[alen-lab] = '\0';
            string str1(a);
            str1 += b;
            a[alen-lab] = t1;
            b[blen-lba] = '\0';
            string str2(b);
            str2 += a;
            printf("%s\n",min(str1,str2).c_str());
        }
    }
    return 0;
}
    原文作者:KMP算法
    原文地址: https://blog.csdn.net/acmore_xiong/article/details/47858375
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞