杭电2019多校第七场 HDU-6646 A + B = C(大数模拟+思维)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=6646

题意:T组样例。每组样例给出a、b、c。三个数,问能否找出整数x、y、z,使得a*10^{x}+b*10^{y}=c*10^{z}

思路:先把a、b、c的末尾0去掉(因为我们可以通过改变x、y、z的值来得到我们需要末尾0。当然,不能减少。),假设去掉后,a、b、c的长度分别为nna、nnb、nnc。

分类讨论:

1、nnc>nna+nnb;显然,要么c的前nna位为a,中间全为0,后nnb位为b;要么前nnb位为b,中间全为0,后nna位为a。

2、nnc<=nna+nnb;要么a的后几位(设为x)和c的后x位相同,然后把b的最后一位移到x+1位,a和b相加,相加后的长度得等于c的剩余长度才行,也就是a加b要全部用完。(如果x==0,并且a+b的后几位(假设为sum)为0,要在c的末尾多加上sum位0,再比较);要么b的后几位(设为x)和c的后x位相同,然后把a的最后一位移到x+1位,a和b相加和c比较(同理,x==0时需要处理)。

另外这题数据有问题,提供一组hack数据。

1

2341 34 134

 

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+10;
int na,nb,nc,nna,nnb,nnc,a0,b0,c0,max0,x,y,z;
int da[N],db[N],d[N];
char a[N],b[N],c[N]; 
bool can;
void checka()
{
	memset(da,0,sizeof(da));
	memset(db,0,sizeof(db));
	memset(d,0,sizeof(d));	
	int ta=nna,tb=nnb,tc=nnc,sum=0,cnt;
	while(ta&&tc&&a[ta]==c[tc])
		ta--,tc--;
	y=nna-ta+max0-b0;
	for(int i=ta,j=0;i>=1;i--)
		da[++j]=a[i]-'0';
	for(int i=tb,j=0;i>=1;i--)
		db[++j]=b[i]-'0';
	cnt=max(ta,tb);
	for(int i=1;i<=cnt;i++)
	{
		d[i+1]=(da[i]+db[i]+d[i])/10;
		d[i]=(da[i]+db[i]+d[i])%10;		
	} 
	if(d[cnt+1]!=0) cnt++;
	if(ta==nna)
	{
		int i=1;
		while(d[i]==0) i++,sum++; 	
	}
	if(!tc) return;
	int i,j; 
	for(i=sum+1,j=tc;j>=1;i++,j--)
		if(d[i]!=c[j]-'0') return ;	
	if(i<=cnt) return ; 	
	can=1;
	x=max0-a0;
	z=max0+sum-c0;
	printf("%d %d %d\n",x,y,z);
	return ;
}
void checkb()
{
	memset(da,0,sizeof(da));
	memset(db,0,sizeof(db));	
	memset(d,0,sizeof(d));
	int ta=nna,tb=nnb,tc=nnc,sum=0,cnt;
	while(tb&&tc&&b[tb]==c[tc])
		tb--,tc--;
	x=nnb-tb+max0-a0;
	for(int i=ta,j=0;i>=1;i--)
		da[++j]=a[i]-'0';
	for(int i=tb,j=0;i>=1;i--)
		db[++j]=b[i]-'0';
	cnt=max(ta,tb);
	for(int i=1;i<=cnt;i++)
	{
		d[i+1]=(da[i]+db[i]+d[i])/10;
		d[i]=(da[i]+db[i]+d[i])%10;		
	} 
	if(d[cnt+1]!=0) cnt++;
	if(tb==nnb)
	{
		int i=1;
		while(d[i]==0) i++,sum++; 	
	}
	if(!tc) return;
	int i,j;
	for(i=sum+1,j=tc;j>=1;i++,j--)
		if(d[i]!=c[j]-'0') return ;
	if(i<=cnt) return ;	
	can=1;
	y=max0-b0;
	z=max0+sum-c0;
	printf("%d %d %d\n",x,y,z);
	return ;
}
void checkab()
{
	for(int i=1;i<=nna;i++)
		if(a[i]!=c[i]) return ;
	for(int i=nna+1;i<=nnc-nnb;i++)
		if(c[i]!='0') return ;
	for(int i=1;i<=nnb;i++)
		if(b[i]!=c[nnc-nnb+i]) return ;
	can=1;
	x=nnc-nna+max0-a0;
	y=max0-b0;
	z=max0-c0;
	printf("%d %d %d\n",x,y,z);
	return ;	
}
void checkba()
{
	for(int i=1;i<=nnb;i++)
		if(b[i]!=c[i]) return ;
	for(int i=nnb+1;i<=nnc-nna;i++)
		if(c[i]!='0') return ;
	for(int i=1;i<=nna;i++)
		if(a[i]!=c[nnc-nna+i]) return ;
	can=1;
	x=max0-a0;
	y=nnc-nnb+max0-b0;
	z=max0-c0;
	printf("%d %d %d\n",x,y,z);
	return ;	
}
int main(void)
{
	int t,l;
	scanf("%d",&t);
	while(t--)
	{	
		can=0;
		scanf("%s%s%s",a+1,b+1,c+1);
		na=strlen(a+1); nb=strlen(b+1); nc=strlen(c+1);				 
		nna=na; nnb=nb; nnc=nc;
		while(a[nna]=='0') nna--;
		while(b[nnb]=='0') nnb--;
		while(c[nnc]=='0') nnc--;
		a0=na-nna; b0=nb-nnb; c0=nc-nnc;
		max0=max(a0,max(b0,c0));
		if(nna+nnb<nnc)
		{
			checkab();
			if(can) continue;
			checkba();	
			if(can) continue;
		}	
		else
		{
			checka();
			if(can) continue;
			checkb();
			if(can) continue;			
		}
		printf("-1\n");
		
	}
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值