您的位置:首页 > 其它

sgu284:Grammar(递推+高精度)

2015-06-27 16:04 211 查看
题目大意:

~~~~~~有nn个字符串,每个字符为aa或bb,第ii个字符串可以表示为若干个a,ba,b和整数j(j<i)j(j((表示第jj个字符串))的组合。

~~~~~~给定一个新的字符串ss,求ss在第nn个字符串中出现了多少次。

分析:

~~~~~~很显然的一个递推关系,处理一下合并的情况就好了,细节有一些,而且要用高精度。

AC code:

[code]#include <cstdio>
#include <cctype>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define debug(...) (fprintf(stderr, __VA_ARGS__))
using namespace std;

const int MAXN = 39;
const int MOD = 1e9;

int n;
int ls;
string s;
string pre[MAXN], suf[MAXN];
struct bi
{
    int len;
    int a[100];
    bi() {len = 1;memset(a, 0, sizeof a);}

    void shift()
    {
        for(int i = 1; i <= len; ++i)
        {
            a[i+1] += a[i]/MOD;
            a[i] %= MOD; 
        }
        while(a[len+1])
        {
            ++len;
            a[len+1] += a[len]/MOD;
            a[len] %= MOD;
        }
        while(!a[len] && len) len--;
        if(!len) len = 1;
    }
    friend bi operator + (const bi &a, const bi &b) 
    {
        bi ret;
        ret.len = max(a.len, b.len);
        for(int i = 1; i <= ret.len; ++i)
            ret.a[i] = a.a[i]+b.a[i];
        ret.shift();
        return ret;
    }
    friend bi operator + (const bi &a, int k) 
    {
        bi ret = a;
        ret.a[1] += k;
        ret.shift();
        return ret;
    }
    friend bool operator > (const bi &a, int k)
    {
        bi b;b.len = 0;
        if(!k) b.len = 1;
        while(k)
        {
            b.a[++b.len] = k%MOD;
            k /= MOD;
        }
        if(a.len > b.len) return true;
        else if(a.len < b.len) return true;
        else
        {
            for(int i = a.len; i >= 1; --i)
                if(a.a[i] > b.a[i]) return true;
                else if(a.a[i] < b.a[i]) return false;
            return false;
        }
    }

    void print()
    {
        printf("%d", a[len]);
        for(int i = len-1; i >= 1; --i)
            printf("%09d", a[i]);
        puts("");
    }

}f[MAXN], l[MAXN];

int count(const string &str)
{
    int ret = 0, j = 0;
    while(j+ls <= str.size())
        ret += str.substr(j, ls) == s, j++;
    return ret;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif

    cin >> n >> s;ls = s.size();
    for(int i = 1, j; i <= n; ++i)
    {
        int L;cin >> L;
        string tmp = "";
        for(int k = 1; k <= L; ++k)
        {
            string sss;cin >> sss;
            if(isdigit(sss[0]))
            {
                if(sss.size() == 1) j = sss[0]-'0';
                else j = (sss[0]-'0')*10+sss[1]-'0';
                if(pre[i].size() < ls-1)
                {
                    pre[i] += pre[j];
                    if(pre[i].size() > ls-1)
                        pre[i] = pre[i].substr(0, ls-1);
                }
                suf[i] += suf[j];
                if(suf[i].size() > ls-1)
                    suf[i] = suf[i].substr(suf[i].size()-ls+1, ls-1);
                f[i] = f[i]+f[j], l[i] = l[i]+l[j], tmp += pre[j];
                if(l[j] > ls-1) 
                {
                    f[i] = f[i]+count(tmp);
                    tmp = suf[j];
                }
            }
            else
            {
                if(pre[i].size() < ls-1) pre[i] += sss[0];
                if(suf[i].size() < ls-1) suf[i] += sss[0];
                else if(ls >= 2) suf[i] = suf[i].substr(1, ls-2)+sss[0];
                l[i] = l[i]+1, tmp += sss[0];
            }
        }
        if(tmp.size()) f[i] = f[i]+count(tmp);
    }
    f
.print();

    #ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    #endif
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: