J - J HDU - 6646(模拟+高精度)

题目链接

思路

  • 题意:给我们一个表达是\(a*10^x+b*10^y=c*10^z\),问在给我们 a、b、c的情况下,是否存在x,y,z 使⬆️式成立,否则输出-1
  • 分析
  1. 这真是一道考验码力的题啊,首相我们考虑当两个数a、b相加等于c,要么是 a或者b与c的位数相同,要么a或者b的位数比c的位数少1(这种情况是通过a+b进位得到与c相同的位数)(这两种情况是常识,哎我这巨弱不知道
  2. 有了上面的基础,我们就对上面的情况进行分类讨论
    1. 我们假设a与c位数相同,但是实际是不一定相同,所以我要把 a与c中按位数多的那个进行补0补齐,在这个之后,就领c - a,得出来一个新的数d,通过判断在 d或b的末尾进行补0,看能否得到这两个数相同(在代码中我们并不是直接补0之后在判断的而是通先对 b 与 d (注意:这个时候我们无法确定个 b、d 那个位数更多,这就关系到失配后的补0挽揪操作了)从左开始能匹配的就先匹配上,到失配的时候在通过补0,能否挽救一下使它们相同)
    2. 我们假设b与c位数相同,同1假设,进行补起操作,之后在相减的d,在通过a与d的匹配比较
    3. 我们假设a比c的位数差1,先把a与c补到等长,然后在c的后面补个0,使其长度+1,然后在令它们相减得d,在通过b与d的匹配比较
    4. 我们假设b比c的位数差1,先把b与c补到等长,然后在c的后面补个0,使其长度+1,然后在令它们相减得d,在通过a与d的匹配比较

3.剩下的就代码细节了。。。。。。。。。。。。。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<stack>
void fre() { freopen("A.txt","r",stdin); freopen("Ans.txt","w",stdout); }
using namespace std;
const int mxn = 1e5 + 10;

char aa[mxn], bb[mxn], cc[mxn];
int a[mxn], b[mxn], c[mxn];
int lena, lenb, lenc;                   //aa bb cc 分别对应的真实长度
int la, lb, lc;                         //对aa bb cc 做变化之后的长度
int tx, ty, tz;                         //表示对应对答案
int deta1, deta2, deta3;

bool check(int A[], int B[], int C[], int LA, int LB, int LC)
{
    deta1 = deta2 = deta3 = 0;          //要再次增加0的数量
    if(LA == LB && A[0] < B[0])
        return false;
    int Res[mxn], L = LA;
    int pos = L - 1, tmp = 0;
    int i, j;
    for(i = LA - 1, j = LB - 1; i >= 0 && j >= 0; i --, j --, pos --)
    {
        A[i] -= tmp;    //解决不够减,进位问题
        tmp = 0;
        Res[pos] = A[i] - B[j];
        if(Res[pos] < 0)
        {
            tmp = 1;
            Res[pos] += 10;
        }
    }
    //继续解决进位问题
    for(i; i >= 0; i --, pos --)
    {
        A[i] -= tmp;
        tmp = 0;
        Res[pos] = A[i];
        if(Res[pos] < 0)
        {
            tmp = 1;
            Res[pos] += 10;
        }
    }
    if(tmp > 0)
        return false;

    //找前第一个非前导0的位置
    for(i = 0; i < LA; i ++)
    {
        if(Res[i])
            break;
    }
    //在Res中找C中的重合部分
    for(j = 0; j < LC && i < LA; j ++, i ++)
    {
        if(Res[i] != C[j])
            return false;
    }
    //对因长度不够导致适配那个字符串进行讨论
    while(i < LA)           //这个时候是 C 这个字符串的长度不够了,导致没法往下面继续匹配了,所以我们要给C这个数组0,但是补的这些0,所对应的Res[i]中的位置都要是0
    {
        if(Res[i] != 0)
            return false;
        deta3 ++;
        i ++;
    }
    while(j < LC)
    {
        if(C[j] != 0)
            return false;
        deta1 ++;
        j ++;
    }
    deta2 = deta1;
    return true;
}

void init1()
{
    tx = ty = tz = 0;
    for(int i = 0; i < lena; i ++)
        a[i] = aa[i] - '0';
    for(int i = 0; i < lenb; i ++)
        b[i] = bb[i] - '0';
    for(int i = 0; i < lenc; i ++)
        c[i] = cc[i] - '0';
    la = lena, lb = lenb, lc = lenc;
    if(la > lc)
    {
        lc = la;
        tz = lc - lenc;
        for(int i = lenc; i < lc; i ++)
            c[i] = 0;
    }
    else if(la < lc)
    {
        la = lc;
        tx = la - lena;
        for(int i = lena; i < la; i ++)
            a[i] = 0;
    }
}

void init2()
{
    tx = ty = tz = 0;
    for(int i = 0; i < lena; i ++)
        a[i] = aa[i] - '0';
    for(int i = 0; i < lenb; i ++)
        b[i] = bb[i] - '0';
    for(int i = 0; i < lenc; i ++)
        c[i] = cc[i] - '0';
    la = lena, lb = lenb, lc = lenc;
    if(lb > lc)
    {
        lc = lb;
        tz = lc - lenc;
        for(int i = lenc; i < lc; i ++)
            c[i] = 0;
    }
    else if(lb < lc)
    {
        lb = lc;
        ty = lb - lenb;
        for(int i = lenb; i < lb; i ++)
            b[i] = 0;
    }
}


int main()
{
    /* fre(); */
    int t; scanf("%d", &t);
    while(t --)
    {
        scanf("%s %s %s", aa, bb, cc);
        lena = strlen(aa), lenb = strlen(bb), lenc = strlen(cc);
        
        // 分四种情况进行讨论
        init1();
        if(check(c, a, b, lc, la, lb))
        {
            tx += deta2, ty += deta3, tz += deta1;
            printf("%d %d %d\n", tx, ty, tz);
            continue;
        }
        init1();
        c[lc ++] = 0;
        tz ++;
        if(check(c, a, b, lc, la, lb))
        {
            tx += deta2, ty += deta3, tz += deta1;
            printf("%d %d %d\n", tx, ty, tz);
            continue;
        }
        init2();
        if(check(c, b, a, lc, lb, la))
        {
            tx += deta3, ty += deta2, tz += deta1;
            printf("%d %d %d\n", tx, ty, tz);
            continue;
        }
        init2();
        c[lc ++] = 0;
        tz ++;
        if(check(c, b, a, lc, lb, la))
        {
            tx += deta3, ty += deta2, tz += deta1;
            printf("%d %d %d\n", tx, ty, tz);
            continue;
        }
        printf("-1\n");
    }

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lql-nyist/p/12736202.html
J