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