首页 > 代码库 > Codeforces 464 C. Substitutes in Number 动态规划法题解
Codeforces 464 C. Substitutes in Number 动态规划法题解
Andrew and Eugene are playing a game. Initially, Andrew has string s, consisting of digits. Eugene sends Andrew multiple queries of type "di?→?ti", that means "replace all digits di in string s with substrings equal to ti". For example, if s?=?123123, then query "2?→?00" transforms s to 10031003, and query "3?→?" ("replace 3 by an empty string") transforms it to s?=?1212. After all the queries Eugene asks Andrew to find the remainder after division of number with decimal representation equal to s by 1000000007 (109?+?7). When you represent s as a decimal number, please ignore the leading zeroes; also if s is an empty string, then it‘s assumed that the number equals to zero.
Andrew got tired of processing Eugene‘s requests manually and he asked you to write a program for that. Help him!
The first line contains string s (1?≤?|s|?≤?105), consisting of digits — the string before processing all the requests.
The second line contains a single integer n (0?≤?n?≤?105) — the number of queries.
The next n lines contain the descriptions of the queries. The i-th query is described by string "di->ti", where di is exactly one digit (from 0 to 9), ti is a string consisting of digits (ti can be an empty string). The sum of lengths of tifor all queries doesn‘t exceed 105. The queries are written in the order in which they need to be performed.
Print a single integer — remainder of division of the resulting number by 1000000007 (109?+?7).
123123 1 2->00
10031003
123123 1 3->
1212
222 2 2->0 0->7
777
1000000008 0
1
Note that the leading zeroes are not removed from string s after the replacement (you can see it in the third sample).
本题使用动态规划法思想。
因为需要一步一步地替换相对应的数字的,如果直接模拟,那么就需要大量插入和删除操作,最快也需要lg(n)的效率,但是最后数列就会变得非常长,这样最后计算结果遍历一次也会超时的。故此使用数据结构加速替换操作,并不是好办法。
这就使用动态规划法从后往前替换,相当于路径压缩了,一步直接把数字替换成最终结果的数字。
也要记录好每个数字最终替换成多少个数位,以便正确计算结果。
可以画树来模拟一下替换操作,那么从叶子节点往根节点替换数字,把所有的路径都直接压缩起来。
#include <stdio.h> #include <stdlib.h> #include <vector> #include <string.h> #include <algorithm> #include <iostream> #include <string> #include <limits.h> #include <stack> #include <queue> #include <set> #include <map> using namespace std; const int MAX_N = (int)1E5 + 1; const int MOD = 1000000007; char s[MAX_N]; char query[MAX_N]; string qnum[MAX_N]; short qid[MAX_N]; int replacement[10], tenpows[10], N; int main() { gets(s); scanf("%d\n", &N); for (int i = 0; i < N; i++) { scanf("%s", query);//gets(query)每次用gets都会出现莫名其妙的错误! qid[i] = query[0] - '0'; qnum[i] = query+3; } for (int i = 0; i < 10; i++) { replacement[i] = i; tenpows[i] = 10; } for (int i = N-1; i >= 0; i--) { long long rm = 0LL, tpow = 1LL; for (size_t j = 0; j < qnum[i].size(); j++) { int num = qnum[i][j] - '0'; tpow = tpow * tenpows[num] % MOD; rm = (rm*tenpows[num]%MOD + replacement[num]) % MOD; } replacement[qid[i]] = (int)rm; tenpows[qid[i]] = (int)tpow; } long long r = 0LL; for (char *p = s; *p; p++) r = (r*tenpows[*p-'0'] + replacement[*p-'0'])%MOD; printf("%I64d", r); return 0; }
Codeforces 464 C. Substitutes in Number 动态规划法题解