ZR#989

ZR#989

先吐槽一下这个ZZ出题人,卡哈希表。
我就不写那个能过的类高精了,直接写哈希的题解

解法:

判断两个数相加结果是否等于第三个数, 可以直接用 hash判断.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>

using namespace std; 

#define LL long long
const int N = 1e5 + 100; 

struct hash {
    int base, mod; 
    int cnt, Hash[N], num[N]; 
    hash() {
        cnt = 0,num[0] = 1; 
        base = 10,mod = 1e9 + 7; 
    }
    void init() {cnt = 0;}
    void insert(int c) {
        cnt++; 
        Hash[cnt] = (1LL * Hash[cnt - 1] * base + c) % mod; 
        num[cnt] = (1LL * num[cnt - 1] * base) % mod; 
    }
    int query(int l, int r) {
        if(l == 1) return Hash[r]; 
        return (Hash[r] - (1LL * Hash[l - 1] * num[r - l + 1] % mod) + mod) % mod; 
    }
    friend bool check(hash &ch, int l1, int r1,hash &b, int l2, int r2, hash &c, int l3, int r3) {
        if((ch.query(l1, r1) + b.query(l2, r2)) % ch.mod != c.query(l3, r3)) return false; 
        return true; 
    }
}Hash[4]; 

char ch[4][N]; 
int len[4], oldlen[4],T;

int main() {
    scanf("%d",&T); 
    while(T--) {
        scanf("%s%s%s", ch[1] + 1, ch[2] + 1, ch[3] + 1); 
        for(int i = 1 ; i <= 3 ; i++) {
            oldlen[i] = len[i] = strlen(ch[i] + 1);
            Hash[i].init(); 
        }
        for(int i = 1 ; i <= 3 ; i++) {
            for(int j = 1 ; j <= len[i] ; j++) {
                Hash[i].insert(ch[i][j] - '0');
            }
        }
        int x = 0, y = 0, z = 0; 
        while(len[3] <= max(len[1], len[2]) + 1) {
            z++; 
            ch[3][++len[3]] = '0'; 
            Hash[3].insert(0); 
        }
        while(len[1] < len[3]) {
            ch[1][++len[1]] = '0'; 
            Hash[1].insert(0); 
        }
        while(len[2] < len[3]) {
            ch[2][++len[2]] = '0'; 
            Hash[2].insert(0); 
        }
        bool flag = 1; 
        for(int i = oldlen[1]; i <= len[1] && flag; i++) {
            if(check(Hash[1], 1, i, Hash[2], 1, len[2] - 1, Hash[3], 1, len[3])) {
                flag = 0; 
                x = i - oldlen[1];
                y = len[2] - 1 - oldlen[2]; 
                break; 
            }
            if(check(Hash[1], 1, i, Hash[2], 1, len[2], Hash[3], 1, len[3])) {
                flag = 0; 
                x = i - oldlen[1];
                y = len[2] - oldlen[2]; 
                break; 
            }
        }
        for(int i = oldlen[2]; i <= len[2] && flag; i++) {
            if(check(Hash[1], 1, len[1] - 1, Hash[2], 1, i, Hash[3], 1, len[3])) {
                flag = 0; 
                x = len[1] - 1 - oldlen[1];
                y = i - oldlen[2]; 
                break; 
            }
            if(check(Hash[1], 1, len[1], Hash[2], 1, i, Hash[3], 1, len[3])) {
                flag = 0; 
                x = len[1] - oldlen[1];
                y = i - oldlen[2]; 
                break; 
            }
        }
        if(flag) puts("-1");
        else printf("%d %d %d\n", x, y, z); 
    }
    //system("pause");
    return 0;
}
posted @ 2019-09-24 21:04  西窗夜雨  阅读(228)  评论(0编辑  收藏  举报