题解 P2104 【二进制】
luckydrawbox · · 题解
题意
模拟二进制加减乘数操作。
分析
先考虑数据存储:
我们可以用一个 int 数组 string 字符串
接下来先解决简单的乘和除的操作:
- 如果是乘法,我们直接
++n就行了,因为这样就相当于在a 数组的末尾加了一位,也就是二进制的左移(* 2 ),不过还要来一步a[n]=0,不然你新加的a_n 可能是上次运算留下的1 。
if(s[i]=='*')a[++n]=0;
- 如果是除法,我们只需
n--就OK了,相当于在a 数组的末尾减了一位,也就是二进制的右移(/2 )。
if(s[i]=='/')n--;
然后处理一下难亿点的加和减:
我们定义一个函数 void jia_jian(int x,int f),进行加减运算,其中 jia_jian(x-1,f),因为题目中说 数据保证+,-操作不会导致最高位的进位与退位 ,所以不用考虑边界。然后,我们需要把进位的 a[x]-=2*f。这样我们就得到了加减运算的通用函数:
void jia_jian(int x,int f)
{
a[x]+=f;
if(a[x]>1||a[x]<0)
{
a[x]-=2*f;
jia_jian(x-1,f);
}
}
剩下的就不用说了,直接上代码:
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+10;//千万千万不要少定义
int n,m,a[N];
string s;
void jia_jian(int x,int f)
{
a[x]+=f;
if(a[x]>1||a[x]<0)//判断a[x]是否需要进位或借位
{
a[x]-=2*f;
jia_jian(x-1,f);//向下一位进位或借位
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%1d",&a[i]);//每次读入一位
}
cin>>s;
for(int i=0;i<m;i++)
{
if(s[i]=='*')a[++n]=0;
if(s[i]=='/')n--;
if(s[i]=='+')jia_jian(n,1);
if(s[i]=='-')jia_jian(n,-1);
}
for(int i=1;i<=n;i++)printf("%d",a[i]);
return 0;
}