[2019杭电多校第七场][hdu6646]A + B = C(hash)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6646

题意为求$a*10^{x}+b*10^{y}=c*10^{z}$满足公式的任意一组解$x,y,z$。

因为c有可能会由$a+b$进位得到,所以先在c后添加0使得c长度最长,然后先固定a的长度为c-1或c,遍历b的长度为b到c。

用hash判断是否相等。再交换b和a的顺序再判断一次。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 const int maxn = 1e5 + 110;
 9 struct hash {
10     int base, mod;
11     int tot, Hash[maxn], xp[maxn];
12     hash() {
13         tot = 0; xp[0] = 1; base = 10; mod = 1e9 + 7;
14     }
15     void init() { tot = 0; }
16     void insert(int c) {
17         tot++;
18         Hash[tot] = (1LL * Hash[tot - 1] * base + c) % mod;
19         xp[tot] = (1LL * xp[tot - 1] * base) % mod;
20     }
21     int query(int l, int r) {
22         if (l == 1) return Hash[r];
23         return (Hash[r] - (1LL * Hash[l - 1] * xp[r - l + 1] % mod) + mod) % mod;
24     }
25     friend bool check(hash &a, int l1, int r1, hash &b, int l2, int r2, hash &c, int l3, int r3) {
26         if ((a.query(l1, r1) + b.query(l2, r2)) % a.mod != c.query(l3, r3)) return false;
27         return true;
28     }
29 
30 }h[4];
31 char a[4][maxn];
32 int len[4], oldlen[4];
33 int main() {
34     int t;
35     scanf("%d", &t);
36     while (t--) {
37         scanf("%s%s%s", a[1] + 1, a[2] + 1, a[3] + 1);
38         for (int i = 1; i <= 3; i++)
39             oldlen[i] = len[i] = strlen(a[i] + 1), h[i].init();
40         for (int i = 1; i <= 3; i++)
41             for (int j = 1; j <= len[i]; j++)
42                 h[i].insert(a[i][j] - '0');
43         int x = 0, y = 0, z = 0;
44         while (len[3] <= max(len[1], len[2]) + 1) {
45             z++;
46             a[3][++len[3]] = '0';
47             h[3].insert(0);
48         }
49         while (len[1] < len[3]) {
50             a[1][++len[1]] = '0';
51             h[1].insert(0);
52         }
53         while (len[2] < len[3]) {
54             a[2][++len[2]] = '0';
55             h[2].insert(0);
56         }
57         int f = 1;
58         for (int i = oldlen[1]; i <= len[1] && f; i++) {
59             if (check(h[1], 1, i, h[2], 1, len[2] - 1, h[3], 1, len[3])) {
60                 f = 0;
61                 x = i - oldlen[1], y = len[2] - 1 - oldlen[2];
62                 break;
63             }
64             if (check(h[1], 1, i, h[2], 1, len[2], h[3], 1, len[3])) {
65                 f = 0;
66                 x = i - oldlen[1], y = len[2] - oldlen[2];
67                 break;
68             }
69         }
70         for (int i = oldlen[2]; i <= len[2] && f; i++) {
71             if (check(h[1], 1, len[1] - 1, h[2], 1, i, h[3], 1, len[3])) {
72                 f = 0;
73                 x = len[1] - 1 - oldlen[1], y = i - oldlen[2];
74                 break;
75             }
76             if (check(h[1], 1, len[1], h[2], 1, i, h[3], 1, len[3])) {
77                 f = 0;
78                 x = len[1] - oldlen[1], y = i - oldlen[2];
79                 break;
80             }
81         }
82         if (f)
83             printf("-1\n");
84         else
85             printf("%d %d %d\n", x, y, z);
86     }
87 }

 

posted @ 2019-08-20 20:38  祈梦生  阅读(270)  评论(0编辑  收藏  举报