zoukankan      html  css  js  c++  java
  • HDU 6740 kmp最小循环节

    题意:
    给一个无线循环小数的前几位,给n,m

    选择其中一种出现在前几位的循环节方式(a个数),循环节的长度b

    使得n*a-m*b最大

    样例:

    2 1

    12.1212

    输出 6 

    选择2,2*1-1*1=1;

    选择12,2*4-2*1=6;

    选择21,2*3-2*1=4;

    选择212,2*3-3*1=3;

    选择1212,2*4-4*1=4;

    思路:

    将小数部分,倒过来,求每个点的最小循环节,kmp中i-next[i]代表最小循环节

    当倒过来的小数部分,n*i-m*(i-next[i])中的最大就是答案

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define il inline
    #define it register int
    #define inf 0x3f3f3f3f
    #define lowbit(x) (x)&(-x)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mod 998244353
    const int maxn=1e7+10;
    ll n,m;
    int nexts[maxn];
    char s[maxn],s2[maxn];
    int p2=0;
    il void GetNext(int l){
        int i=0;
        int j=-1;
        nexts[0]=-1;
        while(i<l){
            if(j==-1 || s2[i]==s2[j]){
                i++;
                j++;
                nexts[i] = j;
            }
            else
                j = nexts[j];
        }
        return;
    }
    int main(){
        while(~scanf("%lld%lld",&n,&m)){
            scanf("%s",s);
            int l=strlen(s);p2=0;
            int i;
            for(i=0;i<l;i++){
                if(s[i]=='.'){
                    break;
                }
            }
            for(int k=l-1;k>i;k--){
                s2[p2++]=s[k];
            }
            GetNext(p2);
            ll maxx=-1e18;
            for(i=1;i<=p2;i++){
                maxx=max(maxx,(ll)i*n-(ll)(i-nexts[i])*m);
                //cout<<i<<" "<<(i-nexts[i])<<endl;
            }
            printf("%lld
    ",maxx);
        }
        return 0;
    }

    kmp模板

    inline void getnext(char *ss){
        mem(ne,0);
        int l=strlen(ss);
        int i=0,j=-1;ne[0]=-1;
        while(i<l){
            if (j == -1 || ss[i] == ss[j])
            {
                i++;
                j++;
                ne[i] = j;
            }
            else{
                j = ne[j];
            }
        }
        return;
    }
    inline int kmp(char *ss,char *s){
        int l=strlen(s),ls=strlen(ss);
        int i=0,j=0,ans=0;
        while(i<l){
            if(j==-1||s[i]==ss[j])
            {
                i++;
                j++;
            }
            else
                j=ne[j];
            if(j==ls)
            {
                ans++;
                j=ne[j];
            }
        }
        return ans;
    }

     待补全

    模板

    int next[maxn];
    string str[maxn];
    void get_next(string s){
        memset(next,0,sizeof(next));
        int len=s.length();
        int i,j;
        j=next[0]=-1;
        i=0;
        while(i<len){
            while(j!=-1&&s[i]!=s[j]) j=next[j];
            next[++i]=++j;
        }
    }
    bool kmp(string a,string b){
        int lena=a.length();
        int lenb=b.length();
        get_next(b);
        int i=0,j=0;
        while(i<lena){
            while(j!=-1&&a[i]!=b[j]) j=next[j];
            i++,j++;
            if(j>=lenb) return true;
        }
        return false;
    }
  • 相关阅读:
    <剑指OFFER18> 18_01_DeleteNodeInList在O(1)时间删除链表结点
    哈夫曼树

    快速排序
    冒泡算法
    Java 缓存机制
    JAVA NIO
    string、stringbuilder、stringbuffer区别
    Java内存泄露的问题调查定位
    使用hibernate 框架搭建的helloworld
  • 原文地址:https://www.cnblogs.com/luoyugongxi/p/12369794.html
Copyright © 2011-2022 走看看