2021.11.3

    今天别人期中考试,所以在校史馆学习。

    校史馆对面的桌子特别像酒吧()

    ——————————

    今天早上搜索了一下noip考纲啊

    所以先学习字符串相关了

    明天建议学习dp+复习今天学的字符串模板(模板附在博客末尾

    今天学习的内容:

     manachar(最长回文子串)

     kmp(学了好几遍了,板子还是不熟🤯)

     最长回文子序列

     字符串模拟

     字符串哈希(自然溢出,双哈希)

     最小表示法(一个环形字符串,从哪个位置开始字典序最小)

    留着以后学的东西

    

 

    然后做了些字符串的题啊,但是完全没有用上今天上午学的这些东西(几乎)

    只能说上面这些知识点遇上再练习

    P1323  删数问题

    P1310       [NOIP2011 普及组] 表达式的值

    P1124  文件压缩

    P1106  删数问题

    P1012  [NOIP1998 提高组] 拼数
    P1015  [NOIP1999 普及组] 回文数
    P1019  [NOIP2000 提高组] 单词接龙
    是一些黄绿蓝题,先做了这些反正是
    这些字符串问题主要是模拟
    
 
    一道dp:P1169  [ZJOI2007]棋盘制作
 
    思路:
    当一个点上下左右颜色均与他不同时标记为true 这一步需n^2
    从头到尾对数组进行dp,当一个点为true,第一种可能是加入原本有的矩形,第二种是新建矩形。
    扫完以后,因为所含有的正方形棋盘必定被包含在矩形内,选取最短边最长的矩形,短边^2即为正方形棋盘的答案。
 
 
    
int manacher() {
    len[0]=0;
    int sum=0;
    mx=0;
    for(int i=1; i<len; i++) {
        if(i<mx)
            len[i]=min(mx-i,len[2*id-i]);
        else
            len[i]=1;
        while(str[i-len[i]]==str[i+len[i]])
            len[i]++;
        if(len[i]+i>mx) {
            mx=len[i]+i;
            id=i;
            sum=max(sum,len[i]);
        }
    }
    return (sum-1);
}

int zuichanghuiwenzixvlie() {
    string str;
    while(cin>>str) {
        int len = str.length();
        memset(dp,0,sizeof(dp));
        for(int i=len-1; i>=0; i--) {
            dp[i][i] = 1;
            for(int j=i+1; j<len; j++) {
                if(str[i] == str[j])
                    dp[i][j] = dp[i+1][j-1] + 2;
                else dp[i][j] = Max(dp[i][j-1],dp[i+1][j]);
            }
        }
        printf("%d\n",dp[0][len-1]);
    }
}
int kmp() {
    cin>>a+1;
    cin>>b+1;
    lb=strlen(b+1);
    la=strlen(a+1);
    int j=0;
    for(int i=2; i<=lb; i++) {
        while(j&&b[j+1]!=b[i])
            j=nex[j];
        if(b[j+1]==b[i])
            j++;
        nex[i]=j;
    }
    j=0;
    for(int i=1; i<=la; i++) {
        while(j&&a[i]!=b[j+1])
            j=nex[j];
        if(b[j+1]==a[i])
            j++;
        if(j==lb) {
            printf("%d\n",i-lb+1);
            j=nex[j];
        }
    }
    for(int i=1; i<=lb; i++) {
        printf("%d ",nex[i]);
    }
}
int minimalRepresentation() { //一个环形字符串,从哪个位置开始字典序最小
    int n = strlen(str);
    int i = 0,j = 1, k = 0;
    while(i<n && j<n && k<n) {
        int t = str[(i+k)%n] - str[(j+k)%n] ;
        if(t == 0)
            k++;
        else {
            if(t>0)
                i+=k+1;
            else
                j+=k+1;
            if(i==j)
                j++;
            k = 0;
        }
    }
    return i < j ? i : j;
}

 

    

posted @ 2021-11-03 15:25  kanateta  阅读(52)  评论(0)    收藏  举报