学过《计算机科学导论》的你应该熟悉“二进制运算”吧?
和十进制不同的是:二进制运算“逢二进一”。下面举一个二进制加法的运算实例:
11101
+ 110
--------
100011
下面请你模拟这个过程。
Input
第一行输入一个正整数T ,表示接下来有 T组数据;
接下来 T行,每行输入两个二进制串 a和b 中间用空格隔开,保证它们长度 < 1e5 并且没有前导 0。
Output
对于每组数据,请按模拟二进制加法,按题目描述的格式输出正确的运算结果,注意换行,没有多余的空格和换行。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 3 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
思路
类似于上学期的高精度加法。采用三个数组储存加数和结果。
从后往前处理加数的每一位,逢二进一,可以用一个变量来标记是否进位。将结果储存在第三个数组,并在最后倒序输出。宽度是结果+2
数组长度比1e5大一些。猜测可能1e5+1e5进位,所以需要更长的数组
代码
#include<stdio.h>
#include<string.h>
#define N 100086
char a[N],b[N],c[N],d[N],e[N],f[N];
void reverse(char a[],int l)
{
char temp;
for(int i=0;i<l/2;i++){
temp=a[i];
a[i]=a[l-1-i];
a[l-1-i]=temp;
}
}
main()
{
int t,la,lb,l,i,j;
char flag;
scanf("%d%*c",&t);
while(t--){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(e,0,sizeof(e));
memset(f,0,sizeof(f));
flag='0';
scanf("%s%s",a,b);
la=strlen(a);
lb=strlen(b);
strcpy(c,a);
strcpy(d,b);
reverse(c,la);
reverse(d,lb);
/*puts(c);
puts(d);*/
if(la>lb){
memset(e,'0',la-lb);
strcat(d,e);
l=la;
}
else if(la<lb){
memset(e,'0',lb-la);
strcat(c,e);
l=lb;
}
else l=la;
for(i=0;i<l;i++){
switch(c[i]+d[i]+flag-'0'*3){
case 3:f[i]='1';flag='1';break;
case 2:f[i]='0';flag='1';break;
case 1:f[i]='1';flag='0';break;
case 0:f[i]='0';flag='0';break;
}
}
if(flag=='1'){
f[i++]='1';
}
for(j=0;j<i-la+2;j++) printf(" ");
puts(a);
printf("+");
for(j=1;j<i-lb+2;j++) printf(" ");
puts(b);
for(j=0;j<i+2;j++) printf("-");
printf("\n");
reverse(f,i);
printf(" %s\n",f);
}
}