UVA10625 GNU = GNU'sNotUnix【字符统计】

Let us define GNU, the recursive acronym for GNU’s Not Unix with the following recursive rules:

  1. G –> GNU’s
  2. N –> Not
  3. U –> Unix

在这里插入图片描述
    In each step we apply all the rules simultaneously. If a character in a string does not have a rule associated with it (there will be at most one rule per character), it remains in the string.
For example if we start with GNU, we get:
Step String
0 GNU
1 GNU’sNotUnix
2 GNU’sNotUnix’sNototUnixnix
3 GNU’sNotUnix’sNototUnixnix’sNotototUnixnixnix
4 GNU’sNotUnix’sNototUnixnix’sNotototUnixnixnix’sNototototUnixnixnixnix
. . . . . .

在这里插入图片描述
    As you can see, the strings are growing larger in every steps. And in certain cases the growth can be quite fast. Fear not, for we’re not interested in the entire string. We just want to know the frequency of a particular character after a finite number of steps.
Input
The first line of the input starts with an integer, T (1 ≤ T ≤ 10), the number of test cases. Then T test cases will follow. The first line of each test case will give you R, (1 ≤ R ≤ 10) the number of rules. In each of the next R lines there will be one rule. The rules are written in the following format: ‘x->S’ (without the quotes). Here x is a single character and S is a sequence of characters. You can assume that the ASCII value of the characters lie in the range 33 to 126, that S will contain no more than 100 characters. You can also assume that the symbols ‘-’ and ‘>’ won’t appear in S. The rules can be immediately recursive, recursive in a cycle or not recursive at all. After the rules, you’ll find an integer Q (1 ≤ Q ≤ 10), the number of queries to follow. Each of the Q queries will be presented in the format “initial string x n” in a single line, where initial string is the string that you have in step 0 (with length between 1 and 100), x is the character whose frequency you should count, and n (1 ≤ n ≤ 10000) is the number of times the rules should be applied. All characters in the initial string will have ASCII values in the range 33 to 126.
Output
For each query, print the number of occurances of the particular character in the result string after applying the rules n times, starting with the initial string. The output will always fit in a 64-bit unsigned integer.
Sample Input
2
3
G->GNU’s
N->Not
U->Unix
2
GNU t 3
GNU N 3
1
A->BAcX
1
ABCcXA c 10000
Sample Output
6
4
20001

问题链接UVA10625 GNU = GNU’sNotUnix
问题简述:(略)
问题分析
    繁琐的字符统计题,不解释。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* UVA10625 GNU = GNU'sNotUnix */

#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long int ULL;

const int FROM = 33, TO = 126;
const int N = 100;
char c, rule[N + 1];
int rcnt[TO + 1][TO + 1];
ULL cnt[TO + 1], tmp[TO + 1];

int main()
{
    int t, r, q, n;
    scanf("%d", &t);
    while(t--) {
        scanf("%d", &r);
        getchar();
        memset(rcnt, 0, sizeof(rcnt));

        while(r--) {
            scanf("%c->%s", &c, rule);
            getchar();
            for(int i = 0; rule[i]; i++)
                rcnt[(int)c][(int)rule[i]]++;
        }

        scanf("%d", &q);
        while(q--) {
            memset(cnt, 0, sizeof(cnt));
            memset(tmp, 0, sizeof(tmp));

            scanf("%s %c %d", rule, &c, &n);
            for(int i = 0; rule[i]; i++)
                cnt[(int)rule[i]]++;
            while(n--) {
                for(int i = FROM; i <= TO; i++) {
                    ULL times = cnt[i];
                    bool flag = false;
                    for(int j = FROM; j <= TO; j ++) {
                        if(rcnt[i][j] > 0) {
                            tmp[j] += times * rcnt[i][j];
                            flag = true;
                        }
                    }
                    if(!flag) tmp[i] += times;      // 考虑字母未转换的情况
                }
                memcpy(cnt, tmp, sizeof(cnt));
                memset(tmp, 0, sizeof(tmp));
            }

            printf("%llu\n", cnt[(int)c]);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值