算法题:poj 2541 Binary Witch(KMP水过,逆序转换)

链接:

http://poj.org/problem?id=2541

分析与总结:

做这题估算了下复杂度,觉得无论KMP再怎么快,这题暴力也肯定要超时的。

想了很久也没想出个好办法,于是决定暴力之,但是TLE了....于是就放了几天。之后看了下discuss ,这题的正解应该是状态压缩dp,不过目前我还不懂,跪了。

之后百度发现也可以用KMP水过,虽然是因为数据水才过的,不过这种思路很巧妙,值得借鉴!

直接暴力是枚举字符串的后面13个的字母,然后再用KMP匹配,这样的话,就绪要枚举多次,分别是 后面的13,12,11....1个字母。但是通过观察可以发现,其实要求的是最长公共后缀! 那么可以把原 来的字符串逆序转换一下,就变成了求最长公共前缀!这样只需要求一次,用字符串的前面13个字母和 原字符串进行匹配一次就够了!

分析与总结:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;  

const int MAXN = 1002000;
const int START = 2000;
char T[MAXN];
int  f[MAXN];
int n,L;  

inline char getFail(char* p,int len){
    int n=strlen(p);
    f[0]=f[1]=0;
    int pos=-1, Max=-1;
    for(int i=1; i<n; ++i){
        int j=f[i];
        while(j && p[i]!=p[j])j=f[j];
        f[i+1] = p[i]==p[j]?1+j:0;
        if(f[i]==13){
            return p[i-f[i]-1];
        }
        if(Max<f[i])
            Max=f[i], pos=i-f[i]-1;
    }
    if(Max==-1)return '0';
    return p[pos];
}  

int main(){
    while(scanf("%d%d%*c",&n,&L)!=EOF){
        char *p;
        char *str = T+START;
        p=str;
        gets(str);
        // 逆序转换
        int len=strlen(str);
        for(int i=0,j=len-1; i<len/2; ++i,--j){
            char t=str[i];
            str[i] = str[j];
            str[j] = t;
        }
        for(int i=0; i<L; ++i){
            *(str-1)=getFail(str,len);
            --str;
            ++len;
        }
        --p;
        while(p>=str){
            putchar(*p);
            --p;
        }
        puts("");
    }
    return 0;
}

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索字符串
, int
, 这题怎么做啊
, include
, acm 算法 暴力
, kmp
, cc2541 ti
, cc2540 cc2541
, 字母大小写转换 算法
, 算法题
, 字母
, 逆序
暴力算法
cc2541、cc2541被动扫描、cc2541中文数据手册、cc2540 cc2541 区别、cc2541蓝牙模块,以便于您获取更多的相关知识。

时间: 2024-07-29 15:09:10

算法题:poj 2541 Binary Witch(KMP水过,逆序转换)的相关文章

算法题之poj 1961 Period(KMP, 最短循环节)

题目链接: POJ  : http://poj.org/problem?id=1961 HDU : http://acm.hdu.edu.cn/showproblem.php?pid=1358 ZOJ   : http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2177 题目大意: 给定一个长度为n的字符串s,求它的每个前缀的最短循环节.换句话说,对于每个i (2<=i<=n),求一个最大的整数K>1(如果K存在),使

算法题:poj 3080 Blue Jeans(KMP匹配,枚举子串)

链接: http://poj.org/problem?id=3080 题目大意: 给出m(2<=m<=10)个DNA序列, 求出这m个序列中最长的公共字串.如果有多个相同长度的, 输出字典序最小的. 分析与总结: 依次枚举所有的子串, 然后再看是否在所有序列中都能够匹配.保存下长度最大且字典序最小的序 列. 代码: #include<iostream> #include<cstdio> #include<cstring> using namespace st

算法题:poj 2752 Seek the Name, Seek the Fame(理解KMP的失配函数!)

链接: http://poj.org/problem?id=2752 题目大意: 给一个字符串S, 求出所有前缀pre,使得这个前缀也正好是S的后缀. 输出所有前缀的结束位置. 例如 "ababcababababcabab", 以下这些前缀也同时是S的后缀 ab  :  位置2 abab  : 位置4 ababcabab : 位置9 ababcababababcabab : 位置 18 分析与总结: 这题,关键在于对KMP的失配函数的理解.只要真正理解了,那么做出来完全不成问题. 下面

算法题:HDU 2594 Simpsons’ Hidden Talents(KMP)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=2594 题目大意: 给两个字符串s1和s2, 求出是s1的前缀并且是s2的后缀的最长的字符串. 分析与总结: 真正理解好KMP算法,这题就是水题. 首先求出s1的失配函数,然后在s2中 寻找s1字符串. 在寻找字符串过程中,会有一个状态值j,这个值表示的是当前在s2中已经匹配 了多少个s1的字符. 所以,全部匹配完后,最后j的值就是以s2的最后一个字符结尾,和s1的前缀相匹 配的最长字符串.也就是所求的

经典算法题每日演练——第七题 KMP算法

原文:经典算法题每日演练--第七题 KMP算法       在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的, 确实kmp算法还是有点饶人的,如果说红黑树是变态级的,那么kmp算法比红黑树还要变态,很抱歉,每次打kmp的时候,输 入法总是提示"看毛片"三个字,嘿嘿,就叫"看毛片算法"吧. 一:BF算法      如果让你写字符串的模式匹配,你可能会很快的写出朴素的bf算法,至少问题是解决了,我想大家很清楚的知

编码-poj 2058算法题Word Encoding完整代码

问题描述 poj 2058算法题Word Encoding完整代码 题目描述 In any language, certain combinations of letters do not appear (or at least appear so seldom that they can be considered non-existent). For instance, there are no English words containing the three letter combin

算法:ural 1018 Binary Apple Tree(树形dp | 经典)

题意 给一棵边有权值的二叉树,节点编号为1-n,1是根节点.求砍掉一些边,只保留q条边,这q条边 构成的子树 的根节点要求是1,问这颗子树的最大权值是多少? 思路 非常经典的一道树形dp题 ,根据我目前做过的题来看,有多道都是由这题衍生出来的. f(i, j) 表示子树i,保留j个节点(注意是 节点)的最大权值.每条边的权值,把它看作是连接的两个节点中的儿子节点的权值. 那么,就可以对所 有i的子树做分组背包,即每个子树可以选择1,2,...j-1条边分配给它. 状态转移为: f(i, j) =

经典算法题每日演练——第八题 AC自动机

原文:经典算法题每日演练--第八题 AC自动机        上一篇我们说了单模式匹配算法KMP,现在我们有需求了,我要检查一篇文章中是否有某些敏感词,这其实就是多模式匹配的问题. 当然你也可以用KMP算法求出,那么它的时间复杂度为O(c*(m+n)),c:为模式串的个数.m:为模式串的长度,n:为正文的长度,那 么这个复杂度就不再是线性了,我们学算法就是希望能把要解决的问题优化到极致,这不,AC自动机就派上用场了.    其实AC自动机就是Trie树的一个活用,活用点就是灌输了kmp的思想,从

一个算法题,求答案啊啊啊啊

问题描述 一个算法题,求答案啊啊啊啊 白班 09:00-18:00 通班 09:00-21:00 每个人每个月通班数量必须等于早中班和中晚班数量之和 早中班 09:00-15:00 中晚班 15:00-21:00 假设:每月按照30计算. 排班规则: 1.每个人每个月固定休息6天连续上班天数不超过7天. 2.每天各班次上班的人数最低需求:8个白班5个通班1个早中班,2个中晚班. 3.每个月每个人的通班天数安排不超过8天. 4.每个人每个月早中班和中晚班的天数之和需要与通班天数相等. 5.每月最多