zoukankan      html  css  js  c++  java
  • ATP 和淡水工厂(factory)

    时间限制:2s 空间限制:512MB
    Background
    在南极旅游的过程中 ATP意识到南极地区有丰富的淡水资源, 于是决定在南极建立淡水工厂,
    向全世界供应冰冰凉的淡水来赚大钱!
    它成功地说服了 zyf2000 和 cloverhxy 作为投资人, 很快一家规模宏大的工厂就轰隆隆地开工
    了。工厂雇佣彩色的北极熊作为工人(工熊) ,利用北极熊锋利的牙齿把冰山啃下来,装在
    瓶子里运到世界各地。
    正在 ATP 的生意越做越大的时候,突然有一个自称税务官的亚马孙土著人来到了南极要对
    ATP收税!可是 ATP 工厂的收益都买吃的了!怎么办!这个时候 zyf2000 想出了办法……
    zyf2000 在参观工厂的时候发现,北极熊们皮毛的颜色种类如果细分下去还真是多!比如绿
    色北极熊就有淡绿,草绿,墨绿和原谅绿多种。大约有 26 种不同的颜色。ATP 它们决定让
    每只工熊剪下一点柔软的毛,给不习惯寒冷的税务官做一条长长的围巾!税务官拿到围巾以
    后很感动,同意宽限一些缴税的时日。同时,他对这条围巾产生了兴趣……
    Description
    这条围巾的颜色分布可以描述为一个长度为 n 的只包含字母 A..Z 的字符串。税务官想知道
    的问题很简单,他定义颜色串 S 的一个 goodstr为既是 S 的前缀也是 S 的后缀的字符串。对
    于 S 的所有 goodstr,他想知道它们的长度分别是多少,以及它在 S 中分别出现了几次。
    Input
    只有一行一个仅由大写字母构成的字符串 S。
    Output
    第一行一个数 k代表 S 串的 goodstr个数;
    接下来 k行,每行两个数字 a 和 b 描述一个 goodstr,a 代表它的长度,b代表它在 S 中的出
    现次数。要求按照 a为关键字从小到大输出。显然每个不同的 goodstr的 a 值互不相同。
    注意:goodstr包括这个字符串本身。

    Sample Input
    ABACABA

    Sample Output
    3
    1 4
    3 2
    7 1

    分析:
    学姐的hu测题
    学姐:真·送分题

    这道题我一看
    KMP+AC自动机
    结果T三个点

    正解:KMP+DP?(乱搞)
    首先求出一个准确的t数组
    (我一般喜欢用t,就是KMP数组,无所谓叫什么啦)
    之后有一个递推式可以计算出答案
    我们从字符串的最后向前统计答案
    cnt[t[i]]+=cnt[i]
    解释一下:
    因为t中记录的都是当前最长的前缀及后缀,
    所以某串的前后一定是一样的,
    这就像一个简陋版的AC自动机,
    只要长串出现过,那么ta的失配一定出现过

    这里写代码片
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    
    using namespace std;
    
    const int N=100005;
    int t[N];
    int ch[N][27],len,tot=0;
    char s[N];
    int word[N],cnt[N],tt;
    
    void doit()
    {
        int i,j;
        len=strlen(s);
        t[0]=-1;
        for (i=0;i<len;i++)
        {
            int x=t[i];
            while (x!=-1&&s[i]!=s[x]) x=t[x];
            t[i+1]=++x;
            cnt[i]=1;
        }
        cnt[len]=1;
        return;
    }
    
    void solve()
    {
        int i,j,now=0;
        for (i=len;i>=0;i--)
            cnt[t[i]]+=cnt[i];
        int f=t[len];
        while (f)
        {
            word[++word[0]]=f;
            f=t[f];
        }
        printf("%d
    ",word[0]+1);
        for (i=word[0];i>=1;i--)
            printf("%d %d
    ",word[i],cnt[word[i]]);
        printf("%d 1",len);
        return;
    }
    
    int main()
    {
        freopen("factory.in","r",stdin);  
        freopen("factory.out","w",stdout);
        scanf("%s",&s);
        doit();
        solve();
        return 0;
    }
  • 相关阅读:
    Application.Current的使用
    .NET中资源文件的使用
    PMP模拟试题与解析(七)
    PMP模拟试题与解析(四)
    RMAN命令简介
    数据库备份和恢复概述
    ORA-14402: updating partition key column would cause a partition change
    RMAN概述
    PLS-00642: local collection types not allowed in SQL statements
    SFTP(Secure File Transfer Protocol)安全的文件传输协议的使用
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673421.html
Copyright © 2011-2022 走看看