HDU 6646 A + B = C (模拟)2019杭电多校第七场 1001

题目大意:

                                                         a*10^{x}+b*10^{y}=c*10^{z}

  给定a,b,c求x,y,z

题目思路:

       可以分为三种情况来考虑。先把全部末尾的0都去掉,再统一反转字符串,方便随后的加减模拟运算。

情况1:c最低的非零位由两者相加得来

             这种情况我们模拟a+b得到的结果看是否非零部分和c的非零部分一样,然后一定要只比较非0部分 这样可以直接包含5+5=10的情况

 

情况2:c的最低非0位由a自己贡献

               这种情况相加的话不容易确定b的位置,或者说很麻烦确定,(队友哈希直接AC),考虑减法,直接减去a,看下得到的数是否非0部分和b的一样。

 

情况3:c的最低非零为由b自己贡献

               这种情况也同样不容易确定a的位置,同情况2处理。

 

模拟的话,头脑要保持清醒,需要什么就处理什么,尽量封装,打一部分就快速验证是否正确,一定要一气呵成,不能断片

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const LL MAXN = 1e6 + 5;
const LL mod = 1e6;
char a[MAXN],b[MAXN],c[MAXN];
char aa[MAXN],bb[MAXN],cc[MAXN];
char dd[MAXN],ee[MAXN],ff[MAXN];
LL len_a,len_b,len_c;    ///a,b,c长度
LL num_a,num_b,num_c;   ///尾0数量
LL idx_a,idx_b,idx_c;  ///非0位置
LL lin[MAXN];
LL mul(char x[],char y[],LL l1,LL l2)   ///大数加法临时结果存入lin数组
{
    for(LL i=0;i<=max(l1,l2)+10;i++){
        lin[i]=0;
    }
    LL l3=max(l1,l2)+1;
    for(LL i=0;i<l3;i++){
        if (i<=l1) lin[i]+=x[i]-'0';
        if (i<=l2) lin[i]+=y[i]-'0';
    }
    for(LL i=0;i<l3;i++){
        if(lin[i]>=10){
            lin[i]-=10;lin[i+1]++;
        }
    }
    if(lin[l3]!=0)l3++;
    return l3;
}
LL dec(char x[],char y[],LL l1,LL l2)    ///大数减法临时结果存入lin数组
{
    if(l1<l2)return -1;
    if(l1==l2 && x[l1]<y[l2])return -1;
    for(LL i=0;i<=max(l1,l2)+5;i++){
        lin[i]=0;
    }
    for(LL i=0;i<l1+1;i++){
        lin[i]=x[i]-'0';
    }
    LL l3=l1+1;
    for(LL i=0;i<l2+1;i++){
        lin[i]-=(y[i]-'0');
    }
    for(LL i=0;i<l3;i++){
        if(lin[i]<0){
            lin[i+1]--,lin[i]+=10;
        }
    }
    if(lin[l3-1]==0)l3--;
    return l3;
}
int main()
{
    LL t;
    scanf("%lld",&t);
    while(t--)
    {
        num_a=0,num_b=0,num_c=0;
        scanf("%s",aa);scanf("%s",bb);scanf("%s",cc);
        len_a=strlen(aa);len_b=strlen(bb);len_c=strlen(cc);
        memcpy(dd,aa,sizeof(aa));
        memcpy(ee,bb,sizeof(bb));
        memcpy(ff,cc,sizeof(cc));
        for(LL i=len_a-1;i>=0;i--){
            if(aa[i]!='0'){
                idx_a=i;break;
            }
            else num_a++;
        }
        for(LL i=len_b-1;i>=0;i--){
            if(bb[i]!='0'){
                idx_b=i;break;
            }
            else num_b++;
        }
        for(LL i=len_c-1;i>=0;i--){
            if(cc[i]!='0'){
                idx_c=i;break;
            }
            else num_c++;
        }
        reverse(aa,aa+idx_a+1);reverse(bb,bb+idx_b+1);reverse(cc,cc+idx_c+1);
        /*********a + b = c 最低位由两个相加得来*********/
        if((cc[0]!=aa[0]&&cc[0]!=bb[0])||(aa[0]-'0'+bb[0]-'0'==10)){
            LL ll3 = mul(aa,bb,idx_a,idx_b);
            bool f=1;
            LL index,num=0;
            for(LL i=0;i<ll3;i++){
                if(lin[i]){
                    index=i;break;
                }
                else num++;
            }
            for(LL i=0;i<idx_c+1;i++){
                if(lin[index++]!=cc[i]-'0')f=0;
            }
            if(f){
                LL Min=min(min(mod-num_a,mod-num_b),mod-num_c+num);
                printf("%lld %lld %lld\n",mod-num_a-Min,mod-num_b-Min,mod-num_c+num-Min);
                continue;
            }
        }
        /**********b = c - a 最低为由a得来**********/
        if(cc[0]==aa[0]){
            LL ll3 = dec(cc,aa,idx_c,idx_a);
            if(ll3!=-1){
                bool f=1;
                LL index=0,num=0;
                for(LL i=0;i<ll3;i++){
                    if(lin[i]!=0){
                        index=i;break;
                    }
                    else num++;
                }
                for(LL i=0;i<idx_b+1;i++){
                    if(lin[index++]!=bb[i]-'0'){
                        f=0;
                    }
                }
                if(f){
                    LL Min=min(min(mod-num_a,mod-num_b+num),mod-num_c);
                    printf("%lld %lld %lld\n",mod-num_a-Min,mod-num_b-Min+num,mod-num_c-Min);
                    continue;
                }
            }
        }
        /*********a = c - b  最低位由b得来**********/
        if(cc[0]==bb[0]){
               // cout<<"mzz"<<endl;
            LL ll3 = dec(cc,bb,idx_c,idx_b);
            if(ll3!=-1){
                bool f=1;
                LL index=0,num=0;
                for(LL i=0;i<ll3;i++){
                    if(lin[i]!=0){
                        index=i;break;
                    }
                    else num++;
                }
                for(LL i=0;i<idx_a+1;i++){
                    if(lin[index++]!=aa[i]-'0'){
                        f=0;
                    }
                }
                if(f){
                    LL Min=min(min(mod-num_a+num,mod-num_b),mod-num_c);
                    printf("%lld %lld %lld\n",mod-num_a+num-Min,mod-num_b-Min,mod-num_c-Min);
                    continue;
                }
            }
        }
        printf("-1\n");
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值