题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6646
(1)先把a,c的末尾补零(a,b都是用数组存的),使它们的长度相同,比如3e5,补零后的a[]对应A[],b[]对应B[]。
那么问题转化为,判断b能否整除(C-A),且除数是10的倍数。
但是A+M=C,可能会产生进位,所以对于这个式子还需要分C是否有进位,所以A和C都要从下标1开始存数,当C有进位时,A还要考虑A[0]的0,所以A[0]和C[1]对应,A[1]和C[2]对应。
一些细节:
1.如果A和C的对应位,第一个不相同的数A[i]>C[i],那么这种情况下肯定无解;
2.(C-A)进行的是不借位的减法,有些位上可能是负数,要从后往前处理,得到正确的(C-A)的值;
3.(C-A)的值可能会有很多前导0,要从第一个非0的位开始和b对应位上的数开始比较,不相等那么b就无法整除(C-A);
4.有可能C的很末尾上的数不为0,但A的很末尾上的数为0, 那么(C-A)很末尾上的数就不为0,这样的话b还是无法整除(C-A)(不过这种情况不用判断也不会wa)
(2)先把b,c末尾补零,使其长度为3e5,分别对应B[],C[],对同样分C有进位和C无进位两字情况判断a能否整除(C-B),和(1)同理。
虽然长度定的是3e5,但是A[],B[],C[]都至少开4e5左右才不会System Error,有点迷?
#include
using namespace std;
typedef long long ll;
const int maxn = 3e5;
const int maxx = 1e5+5;
const int maxt = 4e5;
char a[maxx], b[maxx], c[maxx];
int A[maxt], B[maxt], C[maxt], D[maxt];// 因为会达到A[3e5] 下标从1开始的话
int judge(int A[], int B[], int C[], int lenb) // 传入A+1或者A
{
// A + B * 10^x = C 判断C-A能否在整除B
for(int i = 0; i < maxn; i++) // 末尾补全0后A和C的总长度都是maxn,B的长度也是maxn
if(A[i] != C[i])
{
if(C[i] < A[i]) return -1;// 从高位起, 第一个不相等的数C[i] < A[i],无解
break;
}
for(int i = 0; i < maxn; i++) D[i] = C[i] - A[i];
for(int i = maxn - 1; i> 0; i--) // 从低位开始
if(D[i] < 0)
{
D[i - 1]--;
D[i] += 10; //消除进位
}
int id = 0;
while(!D[id] && id < maxn) id++;// 找到D[i]第一个非0的位
for(int i = 0; i < lenb; i++)
if(D[id + i] != B[i])
return -1;//不能整除
for(int i = lenb; i < maxn; i++)
if(D[id+i]) return -1;//C[i]-A【i】的末尾可能有非0的数,当然不加这个判断也不会wa
return maxn - lenb - id;
}
int main()
{
//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
int t, res;
scanf("%d", &t);
while(t--)
{
memset(A, 0, sizeof(A));
memset(B, 0, sizeof(B));
memset(C, 0, sizeof(C));
scanf("%s%s%s", a, b, c);
int lena = strlen(a), lenb = strlen(b), lenc = strlen(c);
for(int i = 0; i < lena; i++) A[i + 1] = a[i] - '0';
for(int i = 0; i < lenb; i++) B[i + 1] = b[i] - '0';
for(int i = 0; i < lenc; i++) C[i + 1] = c[i] - '0';
if((res = judge(A + 1, B + 1, C + 1, lenb)) != -1)// A + B*10^x = C,C无进位
{
printf("%d %d %d\n", maxn - lena, res, maxn - lenc);
continue;
}
if((res = judge(A, B + 1, C + 1, lenb)) != -1)// A + B*10^x = C,C有进位
{
printf("%d %d %d\n", maxn - lena - 1, res, maxn - lenc);
continue;
}
if((res = judge(B + 1, A + 1, C + 1, lena)) != -1)// A *10^x + B = C ,C无进位
{
printf("%d %d %d\n", res, maxn - lenb, maxn - lenc);
continue;
}
if((res = judge(B, A + 1, C + 1, lena)) != -1 )// A *10^x + B = C ,C有进位
{
printf("%d %d %d\n",res, maxn - lenb - 1, maxn - lenc);
continue;
}
printf("-1\n");
}
return 0;
}