zoukankan      html  css  js  c++  java
  • codechef 营养题 第一弹

    第一弾が始まる!

    定期更新しない!

    来源:http://wenku.baidu.com/link?url=XOJLwfgMsZp_9nhAK15591XFRgZl7f7_x7wtZ5_3T2peHh5XXoERDanUcdxw08SmRj1a5VY1o7jpW1xYv_V1kuYao1Pg4yKdfG4MfNsNAEa

    codechef problems 第一弹

    一.Authentication Failed
    原题题面
    Several days ago Chef decided to register at one of the
    programming sites. For registering he was asked to choose a
    nickname and a password. There was no problem with choosing a
    nickname ("Chef" is his favorite nickname), but choosing a
    password in a secure way seemed to be a real problem for Chef.
    Therefore, he decided to write a program which would generate
    the password of length N consisting of small Latin letters a..z.
    Then Chef successfully registered at the site and saved the
    password in a file (as it was too hard to remember).

    Today Chef decided to visit the site once again. He entered his
    nickname, copied the password from the file... "Authentication
    failed!" was the answer. Trying to understand the reason of
    this, he noticed that the password in his file had length N+K
    instead of N! Sure enough of the source of the problem, Chef
    went straight to his young brother.

    And Chef was right, it was his brother who had inserted K random
    small Latin letters at some random positions (possibly at the
    beginning or at the end) of the password. Chef's brother didn't
    remember what exactly changes he had made at all, but he
    promised that he had done nothing besides inserting letters.

    As there is no other way to recover the password, Chef is now
    starting to remove every possible combination of K letters from
    the password trying to enter (when Chef obtains the same
    password as one of the previously entered passwords, he doesn't
    try to enter using this password again). Now the question is:
    what is the number of times Chef will receive "Authentication
    failed!" as the answer before successful entering in the worst
    case? As the answer might be quite large, output its remainder
    of division by 1009419529.

    Input

    The first line of the input file contains one integer T -- the
    number of test cases (no more than 10). Each test case is
    described by a line containing two integers N and K (1 ≤ N ≤
    10000, 1 ≤ K ≤ 100) separated by a single space, followed by a
    line containing a string of length N+K consisting of small Latin
    letters a..z.

    Output

    For each test case output just one line containing the required
    number modulo 1009419529.

    Example

    Input:
    3
    2 1
    aaa
    3 1
    abcd
    4 2
    ababab

    Output:
    0
    3
    10

    Explanation:
    In the first test case, the password is definitely "aa". In the
    second test case, it can be "abc", "abd", "acd" or "bcd", so in
    the worst case Chef will guess the correct option from the
    fourth attempt, thus making 3 unsuccessful attempts.


    Description
    你把一个长为N的小写字母组成的密码保存在一个txt文件里;一个熊孩子
    在密码的某些位置插入了共计K个字母,注意这里的K个字母不存在重复;
    你决定把密码重新试出来;求最坏的情况下需要试多少次?
    规定:N<=1W,K<=100

    Solution
    我们选择用递推的方式计数
    先设计计数状态吧
    设f[i][j]为前i位中去掉了j位且第i个字符未删除的方案数
    那么我们的递推式是f[i][j]=f[i-1][j]+f[i-2][j-1]+f[i-3][j-2]+...
    直接枚举每次累加的时间复杂度为O(N*K*K),超时
    由于除了f[i-1][j]以外,其他项可以看作是递推矩阵中一个对角线上的
    数字和,即∑f[i-x][j-x+1]
    那么考虑前缀和优化,多加几个数组就行了
    优化后的时间复杂度为O(N*K),O(100W)->AC
    Code

    #include <stdio.h>
    #include <memory.h>
    #define MaxL 10110
    #define MaxK 110
    #define MaxBuf 1<<22
    #define mo 1009419529
    #define RG register
    #define Blue() ((S==T&&(T=(S=B)+fread(B,1,MaxBuf,stdin),S==T))?0:*S++)
    #define dmin(a,b) ((a)<(b)?(a):(b))
    #define dmax(a,b) ((a)>(b)?(a):(b))
    char B[MaxBuf],*S=B,*T=B;
    template<class Type>inline void Rin(RG Type &x){
        x=0;RG int c=Blue();
        for(;c<48||c>57;c=Blue())
            ;
        for(;c>47&&c<58;c=Blue())
            x=(x<<1)+(x<<3)+c-48;
    }
    inline void geTc(char *C){
        char c=Blue();
        for(;c<'a'||c>'z';c=Blue())
            ;
        for(;c>='a'&&c<='z';c=Blue())
            *C++=c;
    }
    char ch[MaxL];
    int kase,n,k,f[MaxL][MaxK],g[MaxL],h[30][MaxL],ans;
    #define FO(x) {freopen(#x".in","r",stdin);}
    int main(){
        FO(cc authen failed);
        Rin(kase);
        while(kase--){
            memset(f,0,sizeof f);
            memset(g,0,sizeof g);
            memset(h,0,sizeof h);
            ans=0;
            Rin(n),Rin(k),geTc(ch);
            f[0][0]=g[0]=1;
            for(RG int i=1;i<=n+k;i++){
                RG int s=ch[i-1]-'a';
                for(RG int j=0;j<=dmin(i-1,k);j++){
                    f[i][j]=(g[i-j-1]-h[s][i-j])%mo;
                    if(i-j==n)(ans+=f[i][j])%=mo;
                    (g[i-j]+=f[i][j])%=mo;
                    (h[s][i-j]+=f[i][j])%=mo;
                }
            }
            printf("%d
    ",(ans-1+mo)%mo);
        }
        return 0;
    }
  • 相关阅读:
    linux命令及相关配置
    EditPlus配置ftp连接linux
    06_事件机制
    HTTP协议简介
    Codeforces Round #691 (Div. 2) C. Row GCD (数学)
    Codeforces Round #690 (Div. 3) E2. Close Tuples (hard version) (数学,组合数)
    牛客编程巅峰赛S2第10场
    Codeforces Round #665 (Div. 2) D. Maximum Distributed Tree (dfs计数,树)
    牛客编程巅峰赛S2第7场
    Codeforces Global Round 12 D. Rating Compression (思维,双指针)
  • 原文地址:https://www.cnblogs.com/keshuqi/p/6357588.html
Copyright © 2011-2022 走看看