zoukankan      html  css  js  c++  java
  • hdu 2087 剪花布条【KMP】

    剪花布条

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

    Problem Description
    一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?
     
    Input
    输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。
     
    Output
    输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。
     
    Sample Input
    abcde a3 aaaaaa aa #
     
    Sample Output
    0 3
     
    Author
    qianneng
     
    Source
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  1686 3746 3336 1358 2091
    #include <map>
    #include <set>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <iostream>
    #include <stack>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <cstdlib>
    //#include <bits/stdc++.h>
    //#define LOACL
    #define space " "
    using namespace std;
    typedef long long Long;
    //typedef __int64 Int;
    typedef pair<int, int> paii;
    const int INF = 0x3f3f3f3f;
    const double ESP = 1e-5;
    const double Pi = acos(-1.0);
    const int MOD = 1e9 + 5;
    const int MAXN = 1000 + 5;
    char str1[MAXN], str2[MAXN];
    int Next[MAXN];
    void make_next(char s[], int m) {
        /*
         部分匹配值就是前缀和后缀的最长的共有元素(下次肯定要移动到共有元素的位置)
         只有一个字符时匹配值为零,在比较下一个字符时如果和最长公共子列的最后一个一
         位与其相等,那么就在将匹配表加上一。如果不相等,那么利用Next往回返找一个下
         标从零开始的新的公共子列。
        */
        int k = 0; Next[0] = 0;
        for (int i = 1; i < m; i++) {
            while(k && s[i] != s[k]) k = Next[k - 1];
            if (s[i] == s[k])  k++;
            Next[i] = k;
        }
    }
    int main() {
        while (scanf("%s", str1) != EOF) {
            if (str1[0] == '#') break;
            scanf("%s", str2);
            int ans = 0, j = 0;
            int len1 = strlen(str1);
            int len2 = strlen(str2);
            make_next(str2, len2);
            /*
            对于被匹配字符来说,该字符的指针i一直向走下去,不会回头。
            如果字符比较在某一位上出现不同,匹配指针就会进行查next表,
            确定该字符对应下一次对比的位置。
            移动位数 = 已匹配字符数 - 对应部分的匹配值
            这样每次当i和j所对应的字符不相同时,直接将j换成所对应的比配值
            再与i所对应的字符作比较。
            */
            for (int i = 0; i < len1; i++) {
                while (j && str1[i] != str2[j]) j = Next[j - 1];
                if (str1[i] == str2[j]) j++;
                if (j == len2) {
                    ans++; j = 0;
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
     


  • 相关阅读:
    web服务器-Apache
    nginx优化
    nginx下载限速
    nginx-URL重写
    HDU 5358 First One 求和(序列求和,优化)
    HDU 5360 Hiking 登山 (优先队列,排序)
    HDU 5353 Average 糖果分配(模拟,图)
    UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。
    HDU 5348 MZL's endless loop 给边定向(欧拉回路,最大流)
    HDU 5344 MZL's xor (水题)
  • 原文地址:https://www.cnblogs.com/cniwoq/p/6770797.html
Copyright © 2011-2022 走看看