9278:旅行——大整数加法、与int的乘法、输出
题目大意:求错排数。需要大整数类。
本题采用10000进制处理。
注意:前导0的处理!!
#include<iostream>
#include<string.h>
using namespace std;
struct Big
{
int digit[1000];
int size;
void init()
{
this->size=0;
memset(this->digit,0,sizeof(this->digit));
}
Big operator +(const Big &A)const
{
int i,n,carry,temp;//carry=进位
Big ans;
ans.init();
n=max(size,A.size);
carry=0;
for (i=0;i<n;i++)
{
temp=digit[i]+A.digit[i]+carry;
carry=temp/10000;
ans.digit[ans.size++]=temp%10000;//注意size赋值
}
if (carry!=0)
ans.digit[ans.size++]=carry;
return ans;
}
Big operator *(int x)const
{
int i,carry,temp;//carry=进位
Big ans;
ans.init();
carry=0;
for (i=0;i<size;i++)
{
temp=digit[i]*x+carry;
ans.digit[ans.size++]=temp%10000;
carry=temp/10000;
}
if (carry!=0)
ans.digit[ans.size++]=carry;
return ans;
}
}f[201];
int main()
{
int i,n,t;
cin>>n;
f[1].size=1;f[1].digit[0]=0;
f[2].size=1;f[2].digit[0]=1;
for (i=3;i<=n;i++)
f[i]=(f[i-1]+f[i-2])*(i-1);
for (i=f[n].size-1;i>=0;i--)//!!!!!!
{
t=f[n].digit[i];
if (i!=f[n].size-1)//第一个数不要加前导0
{
if (t<1000) cout<<0;
if (t<100) cout<<0;
if (t<10) cout<<0;
}
cout<<t;
}
cout<<endl;
return 0;
}
2980:大整数乘法——大整数与大整数的乘法、string到大整数的转化
本题采用10进制(因为方便处理输入)
注意:
1、输入时要逆序存储
2、乘法中两个都是+=
3、注意结果为0时的处理
#include<iostream>
#include<string.h>
#include<string>
#define MAX 4010
using namespace std;
struct Big
{
int size,digit[MAX];
void init()
{
size=0;memset(digit,0,sizeof(digit));
}
Big stringtoBig(string s)
{
Big ans;ans.init();
int i;
ans.size=s.length();
for (i=0;i<s.length();i++)
ans.digit[ans.size-i-1]=s[i]-'0';//注意逆序处理
return ans;
}
Big operator * (const Big &A)const
{
Big ans;ans.init();
int i,j,carry=0;
for (i=0;i<size;i++)
for (j=0;j<A.size;j++)
ans.digit[i+j]+=digit[i]*A.digit[j];//注意+=
for (i=0;i<MAX-1;i++)
{
if (ans.digit[i]>=10)
{
ans.digit[i+1]+=ans.digit[i]/10;//注意+=
ans.digit[i]%=10;
}
}
i=MAX-1;
while (i>=0 && ans.digit[i]==0) i--;//删前导0,注意加i>=0
ans.size=max(1,i+1);//防止0*0也能输出0
return ans;
}
};
int main()
{
string s1,s2;
Big a,b,ans;
int i,t;
cin>>s1>>s2;
a=a.stringtoBig(s1);
b=b.stringtoBig(s2);
ans=a*b;
for (i=ans.size-1;i>=0;i--)
{
t=ans.digit[i];
cout<<t;
}
cout<<endl;
return 0;
}
【模板】2737:大整数除法——大整数除大整数
注意:
1、除数>被除数的情况要单独考虑!
#include<iostream>
#include<string.h>
#include<string>
using namespace std;
struct Big
{
int size,digit[1000];
void init(){size=0;memset(digit,0,sizeof(digit));}
bool operator <= (const Big a)const
{
int i;
if (size==a.size)
{
for (i=size-1;i>=0;i--)
if (digit[i]<a.digit[i])
return true;
else if (digit[i]>a.digit[i])
return false;
return true;
}
else return (size<a.size);
}
Big operator =(const Big a)
{
size=a.size;
memcpy(digit,a.digit,1000);
return *this;
}
Big operator - (const Big a)const
{
int i,carry=0;
Big ans;ans.init();
ans.size=max(size,a.size);
for (i=0;i<ans.size;i++)
{
ans.digit[i]=digit[i]-a.digit[i]-carry;
if (ans.digit[i]<0)
{
carry=1;
ans.digit[i]+=10;
}
else carry=0;
}
while(ans.digit[ans.size]==0) ans.size--;
ans.size++;
return ans;
}
};
Big toBig(string s)//字符串变Big
{
int i;
Big ans;ans.init();ans.size=s.length();
for (i=0;i<s.length();i++)
ans.digit[ans.size-i-1]=s[i]-'0';
return ans;
}
void multen(Big &a)
{
int i;
for (i=a.size;i>0;i--)
a.digit[i]=a.digit[i-1];
a.digit[0]=0;a.size++;
}
Big div(Big a,Big b)
{
int len,i;
Big yu,shang,t,t2;
yu.init();shang.init();
if ( !(b<=a))//注意!!!!
{
shang.digit[shang.size++]=0;
return shang;
}
while(b<=a)
{
t=b;len=0;
while(t<=a)
{
t2=t;
len++;
multen(t);
}
a=a-t2;
shang.size=max(shang.size,len);
shang.digit[len-1]++;
}
for (i=0;i<shang.size;i++)
if (shang.digit[i]>9)
{
shang.digit[i]-=10;shang.digit[i+1]++;
}
if (shang.digit[i]>0) shang.size++;
return shang;
}
int main()
{
int i;
string s1,s2;
cin>>s1;cin>>s2;
Big ans=div(toBig(s1),toBig(s2));
for (i=ans.size-1;i>=0;i--)
cout<<ans.digit[i];
cout<<endl;
return 0;
}
趁热打铁,又敲了一遍。代码看着更舒服了:(且占用内存和运行时间有优化了)
#include<iostream>
#include<string.h>
#include<string>
using namespace std;
struct Big
{
int digit[1001],size;
void init(){size=0;memset(digit,0,sizeof(digit)); }
bool operator<= (const Big &a)
{
int i;
if (size==a.size)
{
for (i=size-1;i>=0;i--)
if (digit[i]<a.digit[i])
return true;
else if (digit[i]>a.digit[i])
return false;
return true;
}
else return (size<a.size);
}
Big operator - (const Big &a)
{
int i;
Big ans;ans.init(); ans.size=size;
for (i=0;i<size;i++)
{
ans.digit[i]=digit[i]-a.digit[i];
if (ans.digit[i]<0)
{
ans.digit[i]+=10;
digit[i+1]--;//注意是被减数-1
}
}
while(ans.digit[ans.size-1]==0) ans.size--;
return ans;
}
};
Big toBig(string s)
{
int i;
Big ans;ans.init();
ans.size=s.length();
for (i=0;i<s.length();i++)
ans.digit[s.length()-i-1]=s[i]-'0';
return ans;
}
void multen(Big &a)
{
int i;
for (i=a.size;i>0;i--)
a.digit[i]=a.digit[i-1];
a.digit[i]=0; a.size++;
}
void div(Big & shang ,Big a,Big b)
{
Big t,t2;
int i,len;
shang.digit[shang.size++]=0;//注意初始化为0
while(b<=a)
{
t=b;len=0;
while(t<=a)
{
t2=t;
multen(t);
len++;
}
shang.size=max(shang.size,len);
shang.digit[len-1]++;
a=a-t2;//注意是-t2
}
for (i=0;i<shang.size;i++)
if (shang.digit[i]>9)
{ shang.digit[i]-=10; shang.digit[i+1]++; }
if (shang.digit[i]>0)
shang.size++;
}
int main()
{
int i;
string s1,s2;
Big ans;ans.init();
cin>>s1>>s2;
div(ans,toBig(s1),toBig(s2));
for (i=ans.size-1;i>=0;i--)
cout<<ans.digit[i];
return 0;
}