HDU - 6646 (杭电多校第七场 A + B = C )思维

题意:给出a,b,c。求x,y,z满足 。

题解:先把a,b,c去掉末尾的0得到A, B, C。这样我们要解的方程就是: 。

  • 如果 , 那么有 , 因为A和B的末尾都不是0
  • 如果 , 那么 和 中至少有一个为0,因为C的末位不是0
    • 根据末位判断一下哪一个是0就好了

但是高精度又慢又写起来很麻烦。所以我们可以采用hash的想法,对一个大质数取mod然后加减乘除判断相等都很容易

btw, 这个题对java相当不友好,用java自带的BigInteger根本过不了,比赛的时候浪费了好几个小时去调高精度的板子。不过取模之后就能大大节省时间

#include 
#include 
#include 
#include 
#define int int64_t
using namespace std;
using pii = pair;
const int mod = 355542559;
const int maxn = 1e6 + 10;

int bin(int x,int n,int MOD){
    int ret = MOD != 1;
    for (x %= MOD; n; n >>= 1,x=x*x%MOD){
        if(n&1)
            ret = ret * x % MOD;
    }
    return ret;
}

inline int get_inv(int x,int p){
    return bin(x, p - 2, p);
}

string remove_zero(const string &a)
{
    int res = 0;
    for (int i = a.length() - 1; i >= 0; i--)
    {
        if (a[i] == '0')
            res++;
        else
            break;
    }
    return a.substr(0, a.length() - res);
}

int powten(int val){
    static vector vec;
    if(vec.size()==0){
        for (int i = 1, cnt = 0; cnt < maxn;cnt++,i=i*10%mod){
            vec.emplace_back(i, cnt);
        }
        sort(vec.begin(), vec.end());
    }
    auto it = lower_bound(vec.begin(), vec.end(), make_pair(val, 0ll));
    if(it->first==val){
        return it->second;
    }
    return -1;
}

int last_digital(const string &str)
{
    int len = str.length() - 1;
    return str[len] - '0';
}

int go(const string& str){
    int res = 0;
    for(auto ch:str){
        res = (res * 10 + ch - '0') % mod;
    }
    return res;
}

int32_t main()
{
    ios::sync_with_stdio(false);
    int _;
    cin >> _;
    while (_--)
    {
        string a, b, c;
        cin >> a >> b >> c;
        string za1 = remove_zero(a);
        string zb1 = remove_zero(b);
        string zc1 = remove_zero(c);
        int ra = a.length() - za1.length();
        int rb = b.length() - zb1.length();
        int rc = c.length() - zc1.length();
        auto za = go(za1);
        auto zb = go(zb1);
        auto zc = go(zc1);

        int m = last_digital(za1);
        int n = last_digital(zb1);
        int p = last_digital(zc1);
        int x = (int)-1e9, y = (int)-1e9, z = (int)-1e9;
        if (m == p)
        {
            auto tmp = (zc - za + mod) % mod;
            int pow = powten(tmp * get_inv(zb,mod) % mod);
            if (pow >= 0)
            {
                x = rb + rc - pow;
                y = ra + rc;
                z = ra + rb - pow;
            }
        }

        if (n == p)
        {
            auto tmp = (zc - zb + mod) % mod;
            int pow = powten(tmp * get_inv(za, mod) % mod);
            if (pow >= 0)
            {
                x = rb + rc;
                y = ra + rc - pow;
                z = ra + rb - pow;
            }
        }
        auto tmp = za + zb;
        int pow = powten(tmp * get_inv(zc, mod) % mod);
        if (pow >= 0)
        {
            x = rb + rc - pow;
            y = ra + rc - pow;
            z = ra + rb;
        }
        if (x == (int)-1e9)
        {
            cout << -1 << endl;
        }
        else
        {
            int _min = min(x, min(y, z));
            x -= _min;
            y -= _min;
            z -= _min;
            int _max = max(x, max(y, z));
            if (_max > int(1e6))
            {
                cout << -1 << endl;
            }
            else
                cout << x << " " << y << " " << z << endl;
        }
    }
}

你可能感兴趣的:(HDU - 6646 (杭电多校第七场 A + B = C )思维)