Description
有一天人诹Lee
在随手帮女神做题,突然女神发现了自己演算纸上的一个式子,但是式子只有两个加数却没有结果,最近在学不同进制加减法的女神忘了这个两个数字是多少进制了(只记得是小于等于10),但是她很好奇在可能的多少进制下这个式子得到的答案长度最长,为了从人赢Lee
手中抢走女神,你需要快速计算出这个答案,例如78+87=? 在10进制下是165,在9进制下是176,而小于等于8的进制显然是不合法的,所以这个式子答案可能的最长长度就是3.
Input
第一行读入一个整数 T(1≤T≤100000) 表示数据组数
接下来有T行
每行含两个数A,B (不超过4位的非0整数)
Output
对于每个数据输出一个数字,表示可能的答案的最大长度
Sample Input
2
78 87
1 1
Sample Output
3
2
思路:当AB同时为负或者同时为正时,很显然,它们的和化为低进制时,数据长度相对较长。注意:当它们的和为负数时,负号也占一个单位长度。
通过例举几个例子时可以发现:无论A、B为正还是为负,把它们的和化为低进制,它们的和的数据长度会较长。但是不要忘记负号也占一个单位长度。
在决定进制时,取a,b中各个数位中最大的数字h,并以h+1为进制。把a+b的和按照h+1进制输出,结果长度最长。
My solution:
/*2016.3.19*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int x[7],y[7],p[20];
int main()
{
int i,j,k,t,n,m,a,b,a1,b1,t1,t2,h1,h2,h,hk;
scanf("%d",&t);
while(t--)
{
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
memset(p,0,sizeof(p));
h1=h2=0;
scanf("%d%d",&a,&b);
if(a>0&&b<0)//把a与b交换,从而可以把 a>0&&b<0和b>0&&a<0 转换为一种情况处理,不影响结果
{
hk=a;
a=b;
b=hk;
}
if(a<0)
a1=-1*a;//如果a<0,先取整数部分,转换到数组中去
else
a1=a;
if(b<0)
b1=-1*b;//如果b<0,先取整数部分,转换到数组中去
else
b1=b;
for(i=1;i<=5;i++)
{
if(a1)
{
x[i]=a1%10;
if(x[i]>h1)//h1记录a中最大的数字
h1=x[i];
a1/=10;
}
else
{
t1=i-1;//t1记录a转化的数组长度
break;
}
}
for(i=1;i<=5;i++)
{
if(b1)
{
y[i]=b1%10;
if(y[i]>h2)//h2记录b中最大的数字
h2=y[i];
b1/=10;
}
else
{
t2=i-1;//t2记录b转化的数组长度
break;
}
}
if(h1>h2)//取a,b中最大的数字
h2=h1;
h2+=1;//确定进制
if(t1>t2)//确定数组长度
h=t1;
else
h=t2;
if(a*b>0)//a<&&b<0和a>0&&b>0两种情况
{
for(i=1;i<=h;i++)
{
p[i]=p[i]+x[i]+y[i];
if(p[i]>=h2)
{
p[i]-=h2;
p[i+1]+=1;
}
}
if(a<0&&b<0)
{
if(p[i])//判断最高位是否进位
printf("%d\n",i+1);
else
printf("%d\n",i);
}
else
{
if(p[i])//判断最高位是否进位
printf("%d\n",i);
else
printf("%d\n",i-1);
}
}
if(a<0&&b>0)//a>0&&b<0和a<0&&b>0两种情况
{
if(a+b>=0)
{
for(i=1;i<=h;i++)
{
if(y[i]<x[i])
{
p[i]=y[i]+h2-x[i];
y[i+1]-=1;
}
else
p[i]=y[i]-x[i];
}
for(i=h;i>=1;i--)
{
if(p[i])
break;
}
printf("%d\n",i);
}
if(a+b<0)
{
for(i=1;i<=h;i++)
{
if(y[i]>x[i])
{
p[i]=x[i]+h2-y[i];
x[i+1]-=1;
}
else
p[i]=x[i]-y[i];
}
for(i=h;i>=1;i--)
{
if(p[i])
break;
}
printf("%d\n",i+1);
}
}
}
return 0;
}